codeforces 455D Serega and Fun

mac2022-06-30  113

目录

codeforces 260D Serega and Fun题意:题解:Code:

codeforces 260D Serega and Fun

题目传送们

题意:

给出长度为\(n\)的序列,要求支持两种操作: 1.将\([l,r]\)区间的数循环右移一位。 2.询问\([l,r]\)区间的数中等于\(k\)的个数。 一共\(q\)次操作,要求对于每一个询问进行回答,并且强制在线。\((1 \leq n,q \leq 10^5 , 1 \leq a_i \leq n)\)

题解:

由于之前写过了\(ORZJRY\) \(I\),然后那题里面也有一个循环位移的操作,于是就想到了用块状链表来写这道题目了...(我才不会说我第一个想到的是树套树)对于循环位移的操作,我们是很好处理的,但是对于询问,我们则需要思考一下了。如果用map存的话,每次更新块内信息是\(log(n)\)的,查询也是\(log(n)\)的,如果用数组存下来的话,每次暴力更新块内信息则是\(log(n)\)的,查询则可以做到\(O(1)\),实际上都不怎么优秀。但仔细想想会发现它的操作实际上只是循环右移一位,所以对于最左边和最右边的两个块,每次位移都只有一个元素会进行更新,所以只需要更新这一个元素即可。然后自己的块状链表写完之后发现并不需要\(Split\)\(Merge\)操作了,反而更像一个分块。。不过跑的还挺快,记得根号次位移之后重构一下块防止被卡。

Code:

#pragma GCC optimize (2,"inline") #include <bits/stdc++.h> using namespace std; typedef long long ll; bool Finish_read; template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;} template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x+'0');} template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('\n');} template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);} /*================Header Template==============*/ #define PAUSE printf("Press Enter key to continue..."); fgetc(stdin); #define fi first #define se second int Blocksz; int n,q,c,ans; int temp[200650],a[200650]; /*==================Define Area================*/ namespace BlockList { struct node { int tmp[850],cnt[100050]; int sz,nxt; }t[505]; queue<int>Q; void Clear(int o) {t[o].sz=0;} void Del(int o) {Q.push(o);Clear(o);} int Newnode() {assert(Q.size());int id=Q.front();Q.pop();return id;} void Init() {for(int i=1;i<=500;i++) Q.push(i);t[0].nxt=-1,t[0].sz=0;} void Debug() { int tot=0; for(int i=0;~i;i=t[i].nxt) { printf("sequence %d:",i); for(int j=1;j<=t[i].sz;j++) { printf("%d ",t[i].tmp[j]); } tot++; printf(" nxt: %d ",t[i].nxt); puts(""); } puts(""); cerr<< "totblock:" << tot << endl; } void Find(int &pos,int &now) { for (now=0;t[now].nxt!=-1&&pos>t[now].sz;now=t[now].nxt) pos-=t[now].sz; } void Insert(int *a) { int nownd=0; for(int i=1;i<=n;i++) { if(t[nownd].sz<Blocksz) { ++t[nownd].sz; t[nownd].tmp[t[nownd].sz]=a[i]; t[nownd].cnt[a[i]]++; } else { int nd=Newnode(); t[nd].nxt=t[nownd].nxt; t[nownd].nxt=nd; nownd=nd; ++t[nownd].sz; t[nownd].tmp[t[nownd].sz]=a[i]; t[nownd].cnt[a[i]]++; } } } void Move(int l,int r) { int lpos=0,rpos=0; Find(l,lpos);Find(r,rpos); int Turn=t[rpos].tmp[r]; if(lpos==rpos) { for(int i=r;i>l;i--) { t[lpos].tmp[i]=t[lpos].tmp[i-1]; } t[lpos].tmp[l]=Turn; return ; } t[rpos].cnt[Turn]--; for(int i=r;i<t[rpos].sz;i++) { t[rpos].tmp[i]=t[rpos].tmp[i+1]; } t[rpos].sz--; t[lpos].sz++; for(int i=t[lpos].sz;i>l;i--) { t[lpos].tmp[i]=t[lpos].tmp[i-1]; } t[lpos].cnt[Turn]++; t[lpos].tmp[l]=Turn; } int Getcnt(int l,int r,int num) { int lpos=0,rpos=0; int res=0; Find(l,lpos);Find(r,rpos); if(lpos==rpos) { for(int i=l;i<=r;i++) { if(t[lpos].tmp[i]==num) { res++; } } return res; } for(int i=l;i<=t[lpos].sz;i++) if(t[lpos].tmp[i]==num) res++; for(int i=1;i<=r;i++) if(t[rpos].tmp[i]==num) res++; for(int i=t[lpos].nxt;i!=rpos;i=t[i].nxt) { res+=t[i].cnt[num]; } return res; } void Rebuild() { int nw=0; for(int i=0;~i;i=t[i].nxt) { for(int j=1;j<=t[i].sz;j++) { temp[++nw]=t[i].tmp[j]; t[i].cnt[t[i].tmp[j]]--; } } for(int i=t[0].nxt;~i;) { t[i].sz=0;Q.push(i); int now=i; i=t[i].nxt; t[now].nxt=-1; } t[0].nxt=-1;t[0].sz=0; Insert(temp); return ; } } using namespace BlockList; int main() { read(n); Blocksz=420; Init(); for(int i=1;i<=n;i++) { read(a[i]); } Insert(a); read(q); while(q--) { int opt; read(opt); if(opt==1) { int l,r; read(l);read(r); l=(l+ans-1)%n+1; r=(r+ans-1)%n+1; if(l>r) swap(l,r); Move(l,r); c++; } if(opt==2) { int l,r,k; read(l);read(r);read(k); l=(l+ans-1)%n+1; r=(r+ans-1)%n+1; k=(k+ans-1)%n+1; if(l>r) swap(l,r); ans=Getcnt(l,r,k); printf("%d\n",ans); } if(c==Blocksz) { Rebuild(); c=0; } } return 0; }

转载于:https://www.cnblogs.com/Apocrypha/p/9845426.html

相关资源:JAVA上百实例源码以及开源项目
最新回复(0)