[Codeforces 455D] Serega and Fun (分块)
2017-01-20 19:34
399 查看
Codeforces - 455D
给定一个长度为 N 的序列,Q 个询问每次询问一个区间,有两种操作
一是将区间内的数向右循环移位
二是询问区间内有多少个数等于 k
其中 N,Q≤105,ai≤N
强制在线
据说正解是一个分块,每操作一定次数之后暴力重构一下
保证每块大小尽量接近
我的做法也是一个分块,每块用一个链表维护一下
位移的话由于是链表,每次操作起来都是常数
然后每个数都不超过 N,所以用一个数组记录一下每块每个数的个数
总的复杂度就是 (NN‾‾√)
然后我原来块开N‾‾√,TLE 55
改成 N‾‾√log2N就 AC了,真是玄学
我估计是因为块多了,STL链表带来的常数就更大了
#pragma comment(linker, "/STACK:102400000,102400000") #include <cstdio> #include <iostream> #include <cstdlib> #include <cstring> #include <algorithm> #include <cmath> #include <cctype> #include <map> #include <set> #include <list> #include <queue> #include <bitset> #include <string> #include <complex> using namespace std; typedef pair<int,int> Pii; typedef long long LL; typedef unsigned long long ULL; typedef double DBL; typedef long double LDBL; #define MST(a,b) memset(a,b,sizeof(a)) #define CLR(a) MST(a,0) #define SQR(a) ((a)*(a)) #define PCUT puts("\n----------") const int maxn=1e5+10; int N,bsiz; list<int> block[350]; unsigned short cnt[350][maxn]; inline void decode(int &x, int last){x = (x+last-1)%N+1;} void update(int,int); int query(int,int,int); int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); #endif while(~scanf("%d", &N)) { bsiz = sqrt(N)*log2(N); for(int i=0; i<=N/bsiz; i++) block[i].clear(); CLR(cnt); for(int i=0,x; i<N; i++) { scanf("%d", &x); block[i/bsiz].push_back(x); cnt[i/bsiz][x] ++; } int Q, ans=0; scanf("%d", &Q); for(int q=0,t,l,r,k; q<Q; q++) { scanf("%d%d%d", &t, &l, &r); decode(l,ans), decode(r,ans); if(l>r) swap(l,r); if(t==1) update(l-1,r-1); else { scanf("%d", &k); decode(k,ans); ans = query(l-1,r-1,k); printf("%d\n", ans); } } } return 0; } void update(int l, int r) { // printf("update: %d %d\n", l, r); if(l==r) return; int ll=l/bsiz, rr=r/bsiz, num; if(ll==rr) //same block { // puts("update: same block"); int idxl = ll*bsiz, idxr = (ll+1)*bsiz-1; if(idxr>=N) idxr=N-1; auto itl = block[ll].begin(), itr = block[ll].end(); itr--; while(idxl<l){idxl++; itl++;} while(idxr>r){idxr--; itr--;} int num = *itr; block[ll].erase(itr); block[ll].insert(itl, num); } else { // puts("update: diff block"); int idx = rr*bsiz; auto it = block[rr].begin(); while(idx<r){idx++; it++;} num = *it; block[rr].erase(it); cnt[rr][num]--; idx = (ll+1)*bsiz-1; if(idx>=N) idx=N-1; it = block[ll].end(); it--; while(idx>l){idx--; it--;} block[ll].insert(it, num); cnt[ll][num]++; // printf("update: tail_num=%d, l=%d\n", num, *it); for(int i=ll; i<rr; i++) { num = block[i].back(); block[i].pop_back(); block[i+1].push_front(num); cnt[i][num]--, cnt[i+1][num]++; } } // puts("updated:"); // for(int i=0; i<4; i++) for(auto now:block[i]) printf("%d ", now); // puts(""); } int query(int l, int r, int k) { // printf("query: %d %d %d\n", l, r, k); int ans=0; int ll=l/bsiz, rr=r/bsiz; // printf("ll:%d rr:%d\n", ll, rr); if(ll==rr) //same block { // puts("query: same block"); int idx=ll*bsiz; auto it=block[ll].begin(); while(idx<l){idx++; it++;} while(idx<=r) { if(*it==k) ans++; idx++; it++; } } else { // puts("query: diff block"); for(int i=ll+1; i<rr; i++) ans += cnt[i][k]; int idx = rr*bsiz; auto it = block[rr].begin(); // printf("right: %d %d\n", idx, *it); while(idx<=r) { // printf("right-now: %d\n", *it); if(*it==k) ans++; idx++; it++; } idx = (ll+1)*bsiz-1; if(idx>=N) idx=N-1; it = block[ll].end(); it--; // printf("left: %d %d\n", idx, *it); while(idx>=l) { // printf("left-now: %d\n", *it); if(*it==k) ans++; idx--; it--; } // printf("ans=%d\n", ans); } return ans; }
相关文章推荐
- 【分块】 codeforces 455D - Serega and Fun
- codeforces 455 D. Serega and Fun (分块+双向链表)
- codeforces 455D 分块
- Codeforces 487D. Conveyor Belts 分块+DP
- [Codeforces 13E] Holes (分块)
- 【并查集分块】Codeforces 475D CGCDSSQ
- codeforces 577E E. Points on Plane(构造+分块)
- Codeforces 785E Anton and Permutation(分块)
- codeforces contest 13 problem E(分块)
- Codeforces 616E Sum of Remainders 【数学分块】
- codeforces 551E GukiZ and GukiZiana 分块
- Codeforces 785E 分块+树状数组
- [除法分块] Codeforces 830C Bamboo Partition
- codeforces 551E. GukiZ and GukiZiana 分块
- CodeForces 13E. Holes 分块处理
- CodeForces 348 C.Subset Sums(分块)
- Codeforces 472G Design Tutorial: Increase the Constraints(分块+FFT)
- Codeforces 474F(分块)
- CodeForces 785E Anton and Permutation 分块
- codeforces 375D. Tree and Queries (莫队+分块)