题目大意:维护一个序列,支持6种操作:
1、ADD x y D 从第x个数到第y个数都增加D
2、REVERSE x y 翻转第x个数到第y个数
3、REVOLVE x y T 从x到y,向右循环移动T次
4、INSERT x P 插入P到第x个数后面
5、DELETE x 删除第x个数
6、MIN x y 查询第x个数到第y个数之间最小值
ADD和REVERSE打标记然后及时下传就可以。。REVOLVE的T可能为负还可能很大,要注意取模。REVOLVE可以通过3个REVERSE操作完成,也可以通过分离和合并完成,只不过代码稍微长一点。INSERT可以将x提到根,x+1提到root下面,此时根节点的右儿子的左儿子为空,新建一个结点,维护信息。也可以将x提到根,新建结点t,使t->ch[1]=root->ch[1],再使root->ch[1]=t。DELETE可以将x-1提到根,x+1提到root下面,删除root->ch[1]->ch[0],维护信息。
代码长,细节多。。容易出错。这题好像RE会显示TLE。。不知道是什么问题
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 const int INF=~0U>>1; 5 const int MAXN=100000+10; 6 int n,m; 7 int a[MAXN]; 8 struct Node{ 9 int s,v,add,mn; 10 bool rev; 11 Node* p,*ch[2]; 12 Node() {s=0;add=0;v=mn=INF;} 13 inline bool d() {return p->ch[1]==this;} 14 inline void setc(Node* o,int d) 15 { 16 ch[d]=o; 17 o->p=this; 18 } 19 inline void addIt(int x) 20 { 21 add+=x; 22 mn+=x; 23 v+=x; 24 } 25 inline void revIt() 26 { 27 rev^=1; 28 } 29 inline void maintain() 30 { 31 s=ch[0]->s+ch[1]->s+1; 32 mn=std::min(v,std::min(ch[0]->mn,ch[1]->mn)); 33 } 34 inline void pushdown(); 35 }Tnull,*null=&Tnull; 36 Node mem[MAXN<<1],*C=mem; 37 inline void Node::pushdown() 38 { 39 if(add) 40 { 41 if(ch[0]!=null) ch[0]->addIt(add); 42 if(ch[1]!=null) ch[1]->addIt(add); 43 add=0; 44 } 45 if(rev) 46 { 47 std::swap(ch[0],ch[1]); 48 if(ch[0]!=null) ch[0]->revIt(); 49 if(ch[1]!=null) ch[1]->revIt(); 50 rev=0; 51 } 52 } 53 inline Node* newnode(int v) 54 { 55 C->ch[0]=C->ch[1]=null; 56 C->s=1; 57 C->v=C->mn=v; 58 C->add=C->rev=0; 59 return C++; 60 } 61 Node* build(int l,int r) //[l,r) 62 { 63 if(l>=r) return null; 64 int m=l+(r-l)/2; 65 Node* t=newnode(a[m]); 66 t->setc(build(l,m),0); 67 t->setc(build(m+1,r),1); 68 t->maintain(); 69 return t; 70 } 71 Node* root; 72 inline void rot(Node* t) 73 { 74 Node* p=t->p; 75 p->pushdown();t->pushdown(); 76 int d=t->d(); 77 p->p->setc(t,p->d()); 78 p->setc(t->ch[d^1],d); 79 t->setc(p,d^1); 80 p->maintain(); 81 if(p==root) 82 root=t; 83 } 84 void splay(Node* t,Node* f=null) 85 { 86 while(t->p!=f) 87 { 88 if(t->p->p==f) rot(t); 89 else t->d()==t->p->d()?(rot(t->p),rot(t)):(rot(t),rot(t)); 90 } 91 t->maintain(); 92 } 93 Node* select(int k) 94 { 95 for(Node* t=root;;) 96 { 97 t->pushdown(); 98 int s=t->ch[0]->s; 99 if(k==s) return t; 100 if(k>s) k-=s+1,t=t->ch[1]; 101 else t=t->ch[0]; 102 } 103 } 104 inline Node*& get(int l,int r) //[l,r) 105 { 106 Node* L=select(l-1); 107 Node* R=select(r); 108 splay(L); 109 splay(R,root); 110 return R->ch[0]; 111 } 112 inline void Reverse(int l,int r) 113 { 114 Node*& t=get(l,r+1); 115 t->revIt(); 116 } 117 inline void Insert(int x,int P) 118 { 119 splay(select(x)); 120 Node* t=newnode(P); 121 t->setc(root->ch[1],1); 122 root->setc(t,1); 123 t->maintain(); 124 root->maintain(); 125 } 126 inline void Add(int x,int y,int D) 127 { 128 Node*& t=get(x,y+1); 129 t->addIt(D); 130 } 131 inline void Revolve(int x,int y,int T) 132 { 133 int l=y+1-x; 134 T=(T%l+l)%l; 135 if(T==0) return; 136 Reverse(x,y); 137 Reverse(x,x+T-1); 138 Reverse(x+T,y); 139 } 140 inline int Min(int x,int y) 141 { 142 Node* &t=get(x,y+1); 143 return t->mn; 144 } 145 inline void Delete(int x) 146 { 147 splay(select(x-1)); 148 splay(select(x+1),root); 149 root->ch[1]->ch[0]=null; 150 root->ch[1]->maintain(); 151 root->maintain(); 152 } 153 int main() 154 { 155 // freopen("1.in","r",stdin); 156 scanf("%d",&n); 157 for(int i=1;i<=n;++i) 158 scanf("%d",a+i); 159 a[0]=a[n+1]=INF; 160 root=build(0,n+2); 161 root->p=null; 162 scanf("%d",&m); 163 while(m--) 164 { 165 int x,y,k; 166 char s[20]; 167 scanf("%s",s); 168 switch(s[0]) 169 { 170 case 'A':scanf("%d%d%d",&x,&y,&k); 171 Add(x,y,k); 172 break; 173 case 'I':scanf("%d%d",&x,&k); 174 Insert(x,k); 175 break; 176 case 'D':scanf("%d",&x); 177 Delete(x); 178 break; 179 case 'M':scanf("%d%d",&x,&y); 180 printf("%d\n",Min(x,y)); 181 break; 182 case 'R':if(s[3]=='E') 183 { 184 scanf("%d%d",&x,&y); 185 Reverse(x,y); 186 } 187 else 188 { 189 scanf("%d%d%d",&x,&y,&k); 190 Revolve(x,y,k); 191 } 192 } 193 } 194 return 0; 195 }