http://poj.org/problem?id=3580
注意,inf設的不要太小,還有對於題目輸入資料的各種處理(可能有非法資料),要注意判斷,具體見代碼
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int inf = ~0u>>2;#define L ch[x][0]#define R ch[x][1] #define KT (ch[ ch[rt][1] ][0])const int maxn = 200010; struct SplayTree {int sz[maxn];int ch[maxn][2];int pre[maxn];int rt,top;inline int min(int a,int b) {return a<b?a:b;}inline void down(int x){if(!x) return ;if(flip[x]) {flip[ L ] ^= 1;flip[ R ] ^= 1;swap(L,R);flip[x]=0;}if(add[x]) {if(L) {mi[L] += add[x];add[L] += add[x];val[L] += add[x];}if(R){mi[R] += add[x];add[R] += add[x];val[R] += add[x];}add[x]=0;}}inline void up(int x){mi[x]=min(val[x],min(mi[ L ],mi[ R ]));sz[x]= 1 + sz[ L ] + sz[ R ];}inline void Rotate(int x,int f){int y=pre[x];down(y);down(x);ch[y][!f] = ch[x][f];pre[ ch[x][f] ] = y;pre[x] = pre[y];if(pre[x]) ch[ pre[y] ][ ch[pre[y]][1] == y ] =x;ch[x][f] = y;pre[y] = x;up(y);}inline void Splay(int x,int goal){//將x旋轉到goal的下面down(x);//防止pre[x]就是目標點,下面的迴圈就進不去了,x的資訊就傳不下去了while(pre[x] != goal){down(pre[pre[x]]); down(pre[x]);down(x);//在旋轉之前需要先下傳標記,因為節點的位置可能會發生改變if(pre[pre[x]] == goal) Rotate(x , ch[pre[x]][0] == x);else {int y=pre[x],z=pre[y];int f = (ch[z][0]==y);if(ch[y][f] == x) Rotate(x,!f),Rotate(x,f);else Rotate(y,f),Rotate(x,f);}}up(x);if(goal==0) rt=x;}inline void RTO(int k,int goal){//將第k位元旋轉到goal的下面int x=rt;down(x);while(sz[ L ]+1 != k) {if(k < sz[ L ] + 1 ) x=L;else {k-=(sz[ L ]+1);x = R;}down(x);}Splay(x,goal);}void vist(int x){if(x){printf("結點%2d : 左兒子 %2d 右兒子 %2d %2d mi:%d sum:%2d add:%2d\n",x,L,R,val[x],mi[x],sum[x],add[x]);vist(L);vist(R);}}void debug(){vist(rt);}void Newnode(int &x,int c,int f){x=++top; L = R = 0; sz[x]=1; pre[x]=f;mi[x]=val[x]=c; flip[x]=add[x]=0; }inline void build(int &x,int l,int r,int f){if(l>r) return ;int m=l+r>>1;Newnode(x,num[m],f);build(L , l , m-1 , x);build(R , m+1 , r , x);pre[x]=f;up(x);}inline void init(int n){ch[0][0]=ch[0][1]=pre[0]=sz[0]=0;rt=top=0; flip[0]=val[0]=add[0]=0; mi[0]=inf;Newnode(rt,inf,0);Newnode(ch[rt][1],inf,rt);sz[rt]=2;for(int i=1;i<=n;i++) scanf("%d",&num[i]);build(KT,1,n,ch[rt][1]);up(ch[rt][1]);up(rt);}void MIN() {int x,y;scanf("%d%d",&x,&y);if(x>y) swap(x,y);RTO(x,0);RTO(y+2,rt);printf("%d\n",mi[KT]);}void ADD() {int x,y,d;scanf("%d%d%d",&x,&y,&d);if(x>y) swap(x,y);RTO(x,0);RTO(y+2,rt);add[KT] += d;val[KT] += d;mi[KT] += d;}void REVERSE(){int x,y;scanf("%d%d",&x,&y);if(x>y) swap(x,y);RTO(x,0);RTO(y+2,rt);flip[KT] ^= 1;}void INSERT() {int x,p;scanf("%d%d",&x,&p);RTO(x+1,0);RTO(x+2,rt);Newnode(KT,p,ch[rt][1]);up(ch[rt][1]);up(rt);}void DELETE() {int x;scanf("%d",&x);RTO(x,0);RTO(x+2,rt);KT = 0;up(ch[rt][1]); up(rt);}void REVOLVE() {int x,y,t,l,r;scanf("%d%d%d",&x,&y,&t);if(x>y) swap(x,y);t%=(y-x+1);t=(t+y-x+1) % (y-x+1);if(t==0) return ;l=y-t+1,r=y;RTO(l,0);RTO(r+2,rt);int tmp=KT;KT=0; up(ch[rt][1]);up(rt);RTO(x,0);RTO(x+1,rt);KT=tmp; pre[tmp] = ch[rt][1];up(ch[rt][1]);up(rt);}int mi[maxn];int num[maxn];int add[maxn];int sum[maxn];int flag;int flip[maxn];int val[maxn];}spt;int main() {int n,m;scanf("%d",&n);spt.init(n);char op[10];scanf("%d",&m);while(m--) {scanf("%s",op);if(op[0]=='A') {spt.ADD();} else if(op[0]=='M') {spt.MIN();} else if(op[0]=='I') {spt.INSERT();} else if(op[0]=='D') {spt.DELETE();} else if(strcmp(op,"REVERSE") == 0) {spt.REVERSE();} else if(strcmp(op,"debug") == 0){spt.debug();} else {spt.REVOLVE();}}return 0;}