L++

Training for 分块&莫队

对着背影说爱祢 提交于 2020-05-05 20:00:01
分块 Study data Link:http://hzwer.com/8053.html // hzwer讲的很好很全 树上莫队Study Link:http://codeforces.com/blog/entry/43230 ( ery nice 并且有题目推荐 莫队算法时间复杂度O( n * sqrt(n) )证明: 由于每一块的大小为sqrt(n),故有sqrt(n)块,按照所属块为first key ,右端点为second key,考虑每一块,因为每块的右端点是Increase,故右端点最大的移动为N ,左端点的最大移动为 k × sqrt(n),故总复杂度为O(n×sqrt(n) + m×sqrt(n)) ≈ O( n * sqrt(n) ) 一道很牛逼的题 题意 给一个n的数的序列,现有q次询问, 1代表是修改操作,2代表是查询操作,对于每次查询输出[1,1e6]以内出现偶数次最小的树(没有出现也算是偶数次) (a[i],n,q<=1e6) 分析 对[1,1e6]分块,每次修改之前的数所在的块和修改后所在的块即可 代码:待补 CDOJ 1324 分析 简单的单点更新,区间最大值 时间复杂度( n×sqrt(n) ) #include<iostream> #include<cstdio> #include<cstring> #include<cmath>

Codeforces 940F Machine Learning (带修改莫队)

这一生的挚爱 提交于 2020-05-05 19:58:02
题目链接 Codeforces Round #466 (Div. 2) Problem F 题意 给定一列数和若干个询问,每一次询问要求集合$\left\{c_{0}, c_{1}, c_{2}, c_{3}, ...,c_{10^{9}}\right\}$的$mex$    同时伴有单点修改的操作。 根据题目询问的这个集合的性质可以知道答案不会超过$\sqrt{n}$,那么每次询问的时候直接暴力找就可以了。 剩下的都是可修改莫队的基本操作。 #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) const int N = 1e5 + 10; int c[N], f[N << 1], vis[N], ans[N]; int a[N], b[N], d[N << 1]; int n, m, bs, et; int cnt = 0, tot = 0; int op, x, y; int l, r; int net, ret; struct node{ int l, r, lb, rb, id, x; friend bool operator <

hihocoder 后缀自动机五·重复旋律8 求循环同构串出现的次数

白昼怎懂夜的黑 提交于 2020-05-04 00:30:22
描述 小Hi平时的一大兴趣爱好就是演奏钢琴。我们知道一段音乐旋律可以被表示为一段数构成的数列。 小Hi发现旋律可以循环,每次把一段旋律里面最前面一个音换到最后面就成为了原旋律的“循环相似旋律”,还可以对“循环相似旋律”进行相同的变换能继续得到原串的“循环相似旋律”。 小Hi对此产生了浓厚的兴趣,他有若干段旋律,和一部音乐作品。对于每一段旋律,他想知道有多少在音乐作品中的子串(重复便多次计)和该旋律是“循环相似旋律”。 解题方法提示 × 解题方法提示 小Hi:我们已经对后缀自动机比较熟悉了,今天我们再来道稍有难度的题。 小Ho:好!这道题目让我们求的是若干串在另一个长串S中各自作为子串出现的次数,只是匹配的方式从完全相等变成了“循环同构”。 小Hi:没错!如果匹配方式是完全相等的话,本题就可以使用AC自动机或者 trie图 完美的解决。 小Ho:既然这个问题也和子串有关系,那么不妨试试后缀自动机。 小Hi:对。和上一期一样,你可以先想想如果询问只有一个串T应该怎么做。 小Ho:嗯,那自然就考虑所有T的循环同构的串在长串S中出现的次数。 小Hi:没错。循环同构有点麻烦,如果我们枚举与T循环同构的串,再依次判断是否在S中出现过。那复杂度至少是O(length(T)^2)的了。 小Ho:恩。比如T="abcd"的话,我们要判断4个串"abcd", "bcda", "cdab", "dabc

Non-boring sequences(启发式分治)

与世无争的帅哥 提交于 2020-05-02 11:57:17
题意: 一个序列被称作是不无聊的,当且仅当,任意一个连续子区间,存在一个数字只出现了一次,问给定序列是否是不无聊的。 思路: 每次找到一个只出现了一次的点,其位置的pos,那么继续分治[L,pos-1],[pos1+1,R];为了保证分治的复杂度,每次的复杂度应该是拆开后较小的哪个。 可以类比启发式合并。 所以我们应该从两头想中间找pos。 #include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; const int maxn= 200010 ; int a[maxn],pre[maxn],lat[maxn]; map< int , int > mp; bool check( int L, int R) { if (L>=R) return true ; int l=L,r= R; rep(i,L,R){ if (i& 1 ){ if (pre[l]<L&&lat[l]> R) return check(L,l- 1 )&&check(l+ 1 ,R); l ++ ; } else { if (pre[r]<L&&lat[r]> R) return check(L,r- 1 )&&check(r+ 1 ,R); r -- ; } } return false ; }

【GDOI2018】D1T2 密码锁(lock)

假如想象 提交于 2020-05-02 07:25:25
题目大意   给出n个数,每次选择任意一个区间加或减1,求最少多少次能在$mod m$意义下全变成0。 Solution   首先我们对于这n个数前后加个零,在$mod m$意义下差分一下。   $f[i]=(a[i]-a[i-1]+m)mod m$   于是区间加减1操作就转换成了在某一位加一,另一位减一。   容易发现,每个数只会加到m或者减到1,而不会有多次循环。   这样我们对差分序列排个序,在前半部分选择$l$减到1,后半部分选择$r$个加到n,($l+r=n$)   这题就没了。 AC Code #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cctype> using namespace std; #define MAXBUF 50000000 char buffer[MAXBUF]; int pos; inline void load(){ fread(buffer, 1 ,MAXBUF,stdin); pos = 0 ; } inline char gchar(){ return buffer[pos++ ]; } inline int rd(){ int ret= 0 ,f= 1 ; char c= gchar(); for (;!

FFT&DFT简单总结(持续更新)

荒凉一梦 提交于 2020-05-02 00:33:04
FFT&DFT简单总结 前言 相信大家都知道大(chou)名(ming)鼎(zhao)鼎(zhu)的 FFT(fake_fake_true)(fast_fast_tle), 并且都有过被它各种玄学操作虐待的经历(大佬请绕路),那么希望这篇详细的FFT简介能够帮到你。 注:本文中的多项式的次数默认为2的整数次幂,实际中如果不是,需在后面补0。 What it is? 快速傅里叶变换(FFT)是一种能在$O(nlogn)$时间内将一个多项式转换为它的点值表示的算法。、 什么?你不知道点值表示? 好吧我也不知道 划重点 设$A(x)$为一个$n-1$次多项式,我们将$n$个不同的$x$带入,得到$n$个$y$,这$n$对$(x,y)$就可以确定1个$n-1$次多项式。 并不会证明 引入 FFT一般用来加速多项式乘法,也就是处理一个A(x)*B(x)的乘积C(x)。 考虑暴力算法,即$O(n^{2})$枚举每一项并相乘。这样做嘛, 太慢了!!! 既然我们刚刚学了点值表示,不妨用点值表示试一试? 一番尝试后我们发现,对于点值表示中的每个$x_{i}$,都有$C(x_{i})=A(x_{i})*B(x_{i})$,而$A(x_{i})$和$B(x_{i})$就是点值表示中的$y_{i}$!如此一来,只要$O(n)$枚举$x_{i}$就可以算出$C(x)$的点值表示,从而得到答案了!

区间求小于等于k的数字个数 hdu4177

我的未来我决定 提交于 2020-04-30 04:21:34
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4417 题目意思给出一个序列,叫我们求一个区间里面小于等于k的数字个数。 这里面我用分块和主席树两种方法都做了一遍,恩,主席树虽然费空间,但是还是比分块块很多的。 因为每个人的风格不一样,所以我的代码可能比较长,比较繁琐。 首先是分块,分块的思想就是把整个区间划分成多个块,用数组来记录每个块的信息,当我们对一个区间进行查询或者修改的时候,一般来说就会有一些块完全的在这个区间里面,对于这种块被区间完全包含的情况,我们就可以对这些块进行整体的操作,把每一块看成一个整体来进行查询或者修改,而对于那种不完整的块(这种块一般就在区间的两头,最多就只有两块是没有完全被包含在区间里面的,其实左右两边的块就算是完整的我们也把它看成不完整的块来处理),我们对它进行暴力修改或者查询。 在这道题目里面,我们把给出的初始序列分块,假设我用a数组来储存,那么我把a数组复制给b数组,对b数组的每一个块进行块内排序,这样当我们查询区间小于等于k的的数字个数时,对于完整的块我们就可以在b数组里面用二分在块内进行查找(b数组是有序的),对于不完整的块,我们将在原来的数组a里面用暴力查找。 代码: #include<iostream> #include <cstring> #include <algorithm>

[bzoj4922]Karp-de-Chant Number

痴心易碎 提交于 2020-04-29 15:03:56
题解: 一道比较好的题目 据说是个经典的贪心模型 首先我们会发现每个括号序列剩下的就是x个)和y个( 然后我们考虑怎么来进行贪心 首先比较显然的是我们会先用x<y的 并且很显然刚开始x需要=0 所以启发我们要对x从小到大排序 来证明一下这个的正确性 假设我们先取一个x比较大的,可能出现)已经比(多的情况 而我们是不希望这种情况出现的,而在贪心过程中,实际上(-)的数目是在不断增加的 那么考虑后半段 我刚开始以为然后就可以随便排了。。 然后测了一下就wa了 我们其实可以把右边看成左边的逆过程(因为我似乎不会正着证明。。。) 所以应该是按照)从大到小排序 代码: #include <bits/stdc++.h> #define rint register int #define IL inline #define rep(i,h,t) for (rint i=h;i<=t;i++) #define dep(i,t,h) for (rint i=t;i>=h;i--) using namespace std; const int N= 310 ; const int INF= 1e9; char c[N]; struct re{ int l,r,len; }a[N * 2 ]; int dp[N][N* N],n; IL void maxa( int &x, int y) { if (x

LOJ_6045_「雅礼集训 2017 Day8」价 _最小割

独自空忆成欢 提交于 2020-04-28 12:19:36
LOJ_6045_「雅礼集训 2017 Day8」价 _最小割 描述: 有$n$种减肥药,$n$种药材,每种减肥药有一些对应的药材和一个收益。 假设选择吃下$K$种减肥药,那么需要这$K$种减肥药包含的药材也等于$K$时才会有效果。 求最小收益,收益可能是负的。保证有完美匹配。 分析: 先把所有权值取相反数求最大收益,因为最小收益看着很难受。 $S$->减肥药($inf$+收益),减肥药->药材($inf$),药材->$T$($inf$)。 然后求最小割,答案就是$S$连出去的边的容量和-最小割。 性质1:割中间的边不会更优。 割左边的边表示不选这种减肥药,割右边的边表示选这种药材。 性质2:加上$inf$后保证左边选取的点数等于右边选取的点数。 性质3:题目存在完美匹配。因此答案一定小于$inf$ 代码: #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define N 2050 #define M 600050 #define inf 100000000 #define S (n*2+1) #define T (n*2+2) typedef long long ll; int head[N],to[M],nxt[M],cnt=1,n,m,dep[N],Q[N],l

Java面试题总结之数据结构、算法和计算机基础(刘小牛和丝音的爱情故事1)

﹥>﹥吖頭↗ 提交于 2020-04-27 20:45:13
Java面试题总结之数据结构、算法和计算机基础(刘小牛和丝音的爱情故事1) ​mp.weixin.qq.com 全文字数: 1703 阅读时间: 大约6 分钟 刘小牛是一名Java程序员,由于天天996平常也不注意锻炼身体,一不小心就进入了ICU,最终抢救无效,告别了人间。死后的刘小牛,被告知需要进入天堂或者地狱,进入天堂需要有一技之长,刘小牛当然想进入天堂了,他思来想去自己也只会敲代码了,所以他来到了天堂的大门前,准备应聘Java程序员,玉帝和王母最疼爱的女儿丝音接待了他,丝音对他说,想要应聘我们天堂的程序员可不简单,我需要问你几个问题,答对了我们才会录用你,让你进入天堂工作,否则你还是去地狱吧,刘小牛说没问题,我这么多年程序员也不是白干的,这点我还是有信心的。下面是他和丝音的对话。 丝音 :你知道一个byte 几个bit位吗? 刘小牛 :这个问题太简单了,一个Byte是8bit。 丝音 :常用UNIX 命令有哪些(Linux 的常用命令)(至少10 个)? 刘小牛 :unix常用命令有: ls 显示指定目录下的文件目录清单相当于dos下的dir命令。 pwd 显示当前目录。 mkdir 在当前目录下创建目录。 rm 删除文件或目录。 cp 复制文件。 mv 移动文件。 cd 切换工作目录。 ps 查看进程。 ftp 传送文件。 telnet 远程登录命令。 ping