3337: ORZJRY I
Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 190 Solved: 50[][][]Description
Jry最近做(屠)了很多数据结构题,所以想 BS你,他希望你能实现一种数据结构维护一个序列:
Input
第一行n;
第二行n个数;第三行q,代表询问个数;接下来q行,每行一个op,输入格式见描述。Output
对于7≤op≤11的操作,一行输出一个答案。
Sample Input
6 5 2 6 3 1 4 15 7 2 4 8 1 3 9 2 4 5 10 1 6 4 11 2 5 4 6 1 4 7 8 1 4 5 3 4 5 2 1 1 2 8 3 3 5 4 1 5 2 9 2 5 4 10 3 6 4 11 1 6 100
Sample Output
11 4 1 4 3 0 3 126
HINT
n,q≤100000;
任意时刻数列中的数≤2^31-1。0≤任意时刻数列中的数≤2^31-1。 本题共3组数据
Source
Solution
switch(opt)
{ case 1: 直接分裂后插入即可 break; case 2: 分裂后直接删除 break; case 3: 分裂得到[l,r]将指向l的块指向r,l指向r指向的块,然后给[l,r]中所有块打上反转标记 break; case 4: 提取出[r-k,r],将这段从中删除,再整段插入到l之前 break; case 5: 提取[l,r],打tag标记 break; case 6: 提取[l,r],打del标记 break; case 7: 提取[l,r],扫描一遍区间中的所有块,统计sum break; case 8: 同上,统计max和min,输出max-min break; case 9: 二分,找到最接近它的两个,统计答案 break; case 10:二分,用下述方法check break; case 11: 二分统计个数 break; }上述这些二分大都可以用upper_bound/lower_bound,注意的是Split和Merge的时候要PushDown和Update
千万不要在查询的时候PushDown...那样复杂度会炸!
Code
(本机AC,OJ TLE)
#include#include #include #include #include #include #include using namespace std;#define LL long longint read(){ int x=0,f=1; char ch=getchar(); while (ch<'0' || ch>'9') { if (ch=='-') f=-1; ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x*f;}#define MAXN 100010int Bsize,N,Q,a[MAXN];namespace BlockLists{ #define BN 5010 struct BLNode{ int next,data[1010],tag,tmp[1010],size,maxx,minn,del; LL sum; bool rev;}B[BN]; int start,ID; queue trash; inline int New() { if (trash.empty()) return ++ID; int tmp=trash.front(); trash.pop(); return tmp;} inline void Del(int x) {trash.push(x); B[x].next=-1; B[x].size=B[x].maxx=B[x].minn=B[x].sum=B[x].tag=B[x].rev=B[x].del=0;} inline int GetP(int rk) { int p; for (p=start; ~B[p].next && rk>B[p].size; p=B[p].next) rk-=B[p].size; return p;} inline int GetK(int rk) { int p; for (p=start; ~B[p].next && rk>B[p].size; p=B[p].next) rk-=B[p].size; return rk;} inline void PushDown(int x) { int sz=B[x].size; if (B[x].del) { int del=B[x].del; B[x].del=0; for (int i=1; i<=sz; i++) B[x].data[i]=del; B[x].sum=sz*del;} if (B[x].rev) {reverse(B[x].data+1,B[x].data+sz+1); B[x].rev^=1;} if (B[x].tag) { int tag=B[x].tag; B[x].tag=0; for (int i=1; i<=sz; i++) B[x].data[i]+=tag; B[x].sum+=(LL)sz*tag;} } inline void Update(int x) { int sz=B[x].size; B[x].sum=0; for (int i=1; i<=sz; i++) B[x].sum+=B[x].data[i],B[x].tmp[i]=B[x].data[i]; sort(B[x].tmp+1,B[x].tmp+sz+1); B[x].minn=B[x].tmp[1],B[x].maxx=B[x].tmp[B[x].size]; } inline void Split(int pos,int rk) { PushDown(pos); int id=New(); for (int i=rk; i<=B[pos].size; i++) B[id].data[++B[id].size]=B[pos].data[i]; B[id].next=B[pos].next; B[pos].next=id; B[pos].size=max(rk-1,0); Update(id); Update(pos); } inline void Merge(int pos) { for ( ; ~pos; pos=B[pos].next) for (int suf=B[pos].next; ~suf && B[pos].size+B[suf].size<=Bsize; suf=B[suf].next) { PushDown(pos),PushDown(suf); for (int k=1; k<=B[suf].size; k++) B[pos].data[++B[pos].size]=B[suf].data[k]; B[pos].next=B[suf].next,Del(suf),Update(pos); } } inline void Insert(int s,int x) { int now=GetP(s+1),pos=GetK(s+1); Split(now,pos); B[now].data[++B[now].size]=x; Update(now); Merge(now); } inline void Delete(int s) { int now=GetP(s),pos=GetK(s); PushDown(now); for (int i=pos+1; i<=B[now].size; i++) B[now].data[i-1]=B[now].data[i]; B[now].size--; Update(now),Merge(now); } inline void Prework(int l,int r,int &x,int &y) { int now1=GetP(l),pos1=GetK(l); Split(now1,pos1); int now2=GetP(r+1),pos2=GetK(r+1); Split(now2,pos2); x=now1,y=GetP(r); } int st[MAXN]; inline void Rever(int l,int r) { int x,y,top=0; Prework(l,r,x,y); for (int i=B[x].next; ~i && i!=B[y].next; i=B[i].next) st[++top]=i,B[i].rev^=1; B[st[1]].next=B[y].next; for (int i=top; i>1; i--) B[st[i]].next=st[i-1]; B[x].next=y; Merge(x); } inline void Move(int l,int r,int k) { int x,y,z,tmp; Prework(l,r-k,x,z); Prework(r-k+1,r,z,y); tmp=B[x].next; B[x].next=B[z].next,B[z].next=B[y].next,B[y].next=tmp; Merge(x); } inline void Add(int l,int r,int D) { int x,y; Prework(l,r,x,y); for (int i=B[x].next; ~i && i!=B[y].next; i=B[i].next) B[i].sum+=(LL)B[i].size*D,B[i].tag+=D; Merge(x); } inline void Modify(int l,int r,int val) { int x,y; Prework(l,r,x,y); for (int i=B[x].next; ~i && i!=B[y].next; i=B[i].next) B[i].tag=0,B[i].del=val,B[i].sum=(LL)B[i].size*val; Merge(x); } inline LL GetSum(int l,int r) { int x,y; LL re=0; Prework(l,r,x,y); for (int i=B[x].next; ~i && i!=B[y].next; i=B[i].next) re+=B[i].sum; Merge(x); return re; } #define INF 0x7fffffff inline int GetRange(int l,int r) { int x,y,maxx=-INF,minn=INF; Prework(l,r,x,y); for (int i=B[x].next; ~i && i!=B[y].next; i=B[i].next) if (B[i].del) maxx=max(maxx,B[i].del+B[i].tag),minn=min(minn,B[i].del+B[i].tag); else maxx=max(maxx,B[i].maxx+B[i].tag),minn=min(minn,B[i].minn+B[i].tag); Merge(x); return maxx-minn; } inline int GetClose(int l,int r,int val) { int x,y,re=INF; Prework(l,r,x,y); for (int t,i=B[x].next; ~i && i!=B[y].next; i=B[i].next) if (B[i].del) re=min(re,abs(val-(B[i].del+B[i].tag))); else { t=lower_bound(B[i].tmp+1,B[i].tmp+B[i].size+1,val-B[i].tag)-B[i].tmp; if (t!=B[i].size+1) re=min(re,abs(B[i].tmp[t]+B[i].tag-val)); if (t!=1) re=min(re,abs(val-(B[i].tmp[t-1]+B[i].tag))); } Merge(x); return re; } inline int GetKth(int l,int r,int k) { int x,y,t=-INF; Prework(l,r,x,y); for (int i=B[x].next; ~i && i!=B[y].next; i=B[i].next) t=max(t,B[i].del? B[i].del+B[i].tag:B[i].maxx+B[i].tag); int L=0,R=t; while (L >1)+1,re=1; for (int i=B[x].next; ~i && i!=B[y].next; i=B[i].next) if (B[i].del) if (B[i].del+B[i].tag =re) L=mid; else R=mid-1; } Merge(x); return L; } inline int GetSmall(int l,int r,int val) { int x,y,re=0; Prework(l,r,x,y); for (int t,i=B[x].next; ~i && i!=B[y].next; i=B[i].next) if (B[i].del) if (B[i].del+B[i].tag
char哥说的对,用数组的我,BZOJ开O2是挽救不了我的....然后我自测AC...无限TLE....
已经生无可恋了。