题目链接: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;
}
View Code