题目链接:http://poj.org/problem?id=3580
有毒。。。poj上不能srand???,然后我就愉快地一直RE,写了个暴力,写了个make,拍了半天,看了半天。。。气死我了~~~~(>_<)~~~~
这题很多人用splay,但我最近学了非旋转treap,就用它来做一下,然后对于这个题很舒服,特别是第3个操作REVOLVE
RE改了半天,一气之下把int全改成long long了。。。
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #include<iostream> #include<string> #include<ctime> #include<queue> #include<map> #include<set> #include<vector> #define mp make_pair #define fi first #define se second #define sqr(x) (x)*(x) #define rep(i,x,y) for (LL i=(x);i<=(y);i++) #define per(i,x,y) for (LL i=(x);i>=(y);i--) using namespace std; typedef long long LL; typedef double DBD; typedef pair<int,int> pa; const LL inf=1e9; const LL INF=1e18; //-----------------------------------------------head-------------------------------------------// const LL N=200010; LL n,m,l[N],r[N],rnd[N],v[N],mn[N],siz[N],lazy[N],cnt,rt; pa a,b,c; bool rev[N]; char s[10]; LL Write[20]; LL read() {LL d=0,f=1; char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();} while (c>='0'&&c<='9') d=(d<<3)+(d<<1)+c-48,c=getchar(); return d*f;} void write(LL x){LL t=0; if (x<0) putchar('-'),x=-x; for (;x;x/=10) Write[++t]=x%10; if (!t) putchar('0'); for (LL i=t;i>=1;i--) putchar((char)(Write[i]+48));} void judge(){freopen("1.in","r",stdin); freopen("1.out","w",stdout);} void flip(LL x){swap(l[x],r[x]); rev[l[x]]^=1; rev[r[x]]^=1;} void add(LL x,LL val){if (!x) return;v[x]+=val;mn[x]+=val;lazy[x]+=val;} void pushup(LL x){siz[x]=siz[l[x]]+siz[r[x]]+1; mn[x]=min(v[x],min(mn[l[x]],mn[r[x]]));} void pushdown(LL x) { if (rev[x]) flip(x),rev[x]=0; if (lazy[x]) add(l[x],lazy[x]),add(r[x],lazy[x]),lazy[x]=0; } pa split(LL x,LL k) { if (!x) return mp(0,0); pa y; pushdown(x); if (siz[l[x]]>=k) y=split(l[x],k),l[x]=y.se,pushup(x),y.se=x; else y=split(r[x],k-siz[l[x]]-1),r[x]=y.fi,pushup(x),y.fi=x; return y; } LL merge(LL x,LL y) { if (!x||!y) return x+y; if (rnd[x]<rnd[y]) {pushdown(x);r[x]=merge(r[x],y);pushup(x);return x;} else {pushdown(y);l[y]=merge(x,l[y]);pushup(y);return y;} } LL newnode(LL x){cnt++;v[cnt]=mn[cnt]=x;siz[cnt]=1;rnd[cnt]=rand();return cnt;} LL get_interval(LL l,LL r){a=split(rt,l-1);b=split(a.se,r-l+1);return b.fi;} void bounce(){LL t=merge(b.fi,b.se); rt=merge(a.fi,t);} void ins(LL x,LL v) { pa y=split(rt,x); rt=merge(y.fi,newnode(v)); rt=merge(rt,y.se); } void del(LL x) { pa y=split(rt,x-1),z=split(y.se,1); rt=merge(y.fi,z.se); } LL query(LL l,LL r) { LL t=get_interval(l,r); write(mn[t]); puts(""); bounce(); } void update(LL l,LL r,LL val) { LL t=get_interval(l,r); add(t,val); bounce(); } void reverse(LL l,LL r) { LL t=get_interval(l,r); rev[t]^=1; bounce(); } void revolve(LL l,LL r,LL len) { len%=(r-l+1); if (!len) return; a=split(rt,r-len); b=split(a.fi,l-1); c=split(a.se,len); LL t1=merge(b.fi,c.fi),t2=merge(b.se,c.se); rt=merge(t1,t2); } int main() { //judge(); v[0]=inf; mn[0]=inf; //srand(time(0)); n=read(); for (LL i=1;i<=n;i++) rt=merge(rt,newnode(read())); m=read(); while (m--) { scanf("%s",s); LL x=read(),y,z; pa a,b; if (s[0]=='A') y=read(),z=read(),update(x,y,z); if (s[0]=='R'&&s[3]=='E') reverse(x,read()); if (s[0]=='R'&&s[3]=='O') y=read(),z=read(),revolve(x,y,z); if (s[0]=='I') ins(x,read()),n++; if (s[0]=='D') del(x),n--; if (s[0]=='M') query(x,read()); } return 0; }