标签:答案 nbsp 也有 莫队算法 sizeof blank pre 程序 tar
被splay折磨了一个星期还是抄模板都wa,调试的时候查数据都发现数据太大不能查的蒟蒻杨澜决定学习莫队算法,
莫队这个东西就是一个非常简♂单的类似动规的东西,也是那种不会就一直不会,一看题解秒懂的题,[虽然我看题解也半天看不懂但是只是第一道题,万事开头难嘛(也许吧)]
我们先按照左端点排序,然后分块。
然后在每个块内按右端点排序。
然后顺序处理即可。块内复杂度:
因为块内右端点是递增的,所以右端点至多变化O(n)次,而左端点 不一定,所以是O(l*l)=O(n)次。
块间跳转:撑死了O(n)。
总复杂度:O(n^1.5)。1 p=(int)sqrt(m*1.0); 2 for(int i=1;i<=m/p;i++){ 3 memset(cnt,0,sizeof(cnt)); 4 sort(e+(i-1)*p+1,e+i*p+1,mycmp); 5 long long l=0,r=0,ans=0; 6 cnt[0]++; 7 for(int j=(i-1)*p+1;j<=i*p;j++){ 8 while(r<e[j].y) {r++,ans+=cnt[a[r]^k],cnt[a[r]]++;} 9 /*从异或的性质可以知道如果a[r]^k=z,那么z^a[r]=k; 10 cnt[z]指的是o∈(l,r](左开右闭是因为l声明为0...)满足从第1到第o个数的异或和是z的o有多少个...好麻烦... 11 那么为什么是+cnt[z]? 12 因为a[r]是从1到r的异或和,如果a[r]^一个1到o的异或和=k,那么从o到r的异或和就是k*/ 13 while(l<e[j].x-1){cnt[a[l]]--,ans-=cnt[a[l]^k],l++;} 14 while(l>e[j].x-1){l--,ans+=cnt[a[l]^k],cnt[a[l]]++;} 15 e[j].ans=ans; 16 } 17 }
标签:答案 nbsp 也有 莫队算法 sizeof blank pre 程序 tar
原文地址:http://www.cnblogs.com/137shoebills/p/7783739.html