poj3580supermemo【splay】
来源:互联网 发布:软件行业的发展 编辑:程序博客网 时间:2024/06/06 09:48
Description
Your friend, Jackson is invited to a TV show called SuperMemo in which the participant is told to play a memorizing game. At first, the host tells the participant a sequence of numbers, {A1,A2, ... An}. Then the host performs a series of operations and queries on the sequence which consists:
- ADD x y D: Add D to each number in sub-sequence {Ax ...Ay}. For example, performing "ADD 2 4 1" on {1, 2, 3, 4, 5} results in {1, 3, 4, 5, 5}
- REVERSE x y: reverse the sub-sequence {Ax ... Ay}. For example, performing "REVERSE 2 4" on {1, 2, 3, 4, 5} results in {1, 4, 3, 2, 5}
- REVOLVE x y T: rotate sub-sequence {Ax ... Ay}T times. For example, performing "REVOLVE 2 4 2" on {1, 2, 3, 4, 5} results in {1, 3, 4, 2, 5}
- INSERT x P: insert P after Ax. For example, performing "INSERT 2 4" on {1, 2, 3, 4, 5} results in {1, 2, 4, 3, 4, 5}
- DELETE x: delete Ax. For example, performing "DELETE 2" on {1, 2, 3, 4, 5} results in {1, 3, 4, 5}
- MIN x y: query the participant what is the minimum number in sub-sequence {Ax ...Ay}. For example, the correct answer to "MIN 2 4" on {1, 2, 3, 4, 5} is 2
To make the show more interesting, the participant is granted a chance to turn to someone else that means when Jackson feels difficult in answering a query he may call you for help. You task is to watch the TV show and write a program giving the correct answer to each query in order to assist Jackson whenever he calls.
Input
The first line contains n (n ≤ 100000).
The following n lines describe the sequence.
Then follows M (M ≤ 100000), the numbers of operations and queries.
The following M lines describe the operations and queries.
Output
For each "MIN" query, output the correct answer.
Sample Input
51 2 3 4 52ADD 2 4 1MIN 4 5
Sample Output
5
依旧是几种基本操作的组合==值得注意的是:
1.由于要求的是区间最小值,初始化的值(没有用的点)就得初始化为inf
2.有一个脑残的错误
Update_Same(int r,int v){ if(!r)return; key[r]+=v; sum[r]+=v;当中sum[r]不能附成key[r]
3.为了以防万一
sum[r]=key[r]; if(ch[r][0]) sum[r]=min(sum[r],sum[ch[r][0]]); if(ch[r][1]) sum[r]=min(sum[r],sum[ch[r][1]]);4.右移的操作可以看做是剪切一段挪过去~~就和上个题一样啦~·~
#include <iostream>#include <string.h>#include <stdio.h>#include <algorithm>using namespace std;#define Key_value ch[ch[root][1]][0]const int MAXN=200010;const int INF=0x3f3f3f3f;int pre[MAXN],ch[MAXN][2],key[MAXN],size[MAXN];int sum[MAXN],rev[MAXN],same[MAXN];int lx[MAXN],rx[MAXN],mx[MAXN];int root,tot1;int s[MAXN],tot2;int a[MAXN];int n,q;void NewNode(int &r,int father,int k){ if(tot2)r=s[tot2--]; else r=++tot1; pre[r]=father; ch[r][0]=ch[r][1]=0; key[r]=k; sum[r]=k; rev[r]=same[r]=0; // lx[r]=rx[r]=mx[r]=k; size[r]=1;}void Update_Same(int r,int v){ if(!r)return; key[r]+=v; sum[r]+=v; // lx[r]=rx[r]=mx[r]=max(v,v*size[r]); same[r]+=v;}void Update_Rev(int r){ if(!r)return; swap(ch[r][0],ch[r][1]); // swap(lx[r],rx[r]); rev[r]^=1;//这里要注意,一定是异或1}void Push_Up(int r){ int lson=ch[r][0],rson=ch[r][1]; size[r]=size[lson]+size[rson]+1; //-1!!! sum[r]=key[r]; if(ch[r][0]) sum[r]=min(sum[r],sum[ch[r][0]]); if(ch[r][1]) sum[r]=min(sum[r],sum[ch[r][1]]);}void Push_Down(int r){ if(same[r]) { Update_Same(ch[r][0],same[r]);//!! Update_Same(ch[r][1],same[r]); same[r]=0; } if(rev[r]) { Update_Rev(ch[r][0]); Update_Rev(ch[r][1]); rev[r]=0; }}void Build(int &x,int l,int r,int father){ if(l>r)return; int mid=(l+r)/2; NewNode(x,father,a[mid]); Build(ch[x][0],l,mid-1,x); Build(ch[x][1],mid+1,r,x); Push_Up(x);}void Init(){ for(int i=1;i<=n;i++)scanf("%d",&a[i]); root=tot1=tot2=0; ch[root][0]=ch[root][1]=pre[root]=size[root]=same[root]=0; sum[root]=INF; // key[root]=0; NewNode(root,0,INF); NewNode(ch[root][1],root,INF);//头尾各加入一个空位 Build(Key_value,1,n,ch[root][1]); Push_Up(ch[root][1]); Push_Up(root);}void Rotate(int x,int kind){ int y=pre[x]; Push_Down(y); Push_Down(x); ch[y][!kind]=ch[x][kind]; pre[ch[x][kind]]=y; if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y]=x; pre[x]=pre[y]; ch[x][kind]=y; pre[y]=x; Push_Up(y);}void Splay(int r,int goal){ Push_Down(r); while(pre[r]!=goal) { if(pre[pre[r]]==goal) { Push_Down(pre[r]); Push_Down(r); Rotate(r,ch[pre[r]][0]==r); } else { Push_Down(pre[pre[r]]); Push_Down(pre[r]); Push_Down(r); int y=pre[r]; int kind=ch[pre[y]][0]==y; if(ch[y][kind]==r) { Rotate(r,!kind); Rotate(r,kind); } else { Rotate(y,kind); Rotate(r,kind); } } } Push_Up(r); if(goal==0)root=r;}int Get_Kth(int r,int k){ Push_Down(r); int t=size[ch[r][0]]+1; if(t==k)return r; if(t>k)return Get_Kth(ch[r][0],k); else return Get_Kth(ch[r][1],k-t);}//在第pos个数后插入tot个数void Insert(int pos,int tot,int tmp){ // for(int i=0;i<tot;i++)a[i]=tmp; Splay(Get_Kth(root,pos+1),0); Splay(Get_Kth(root,pos+2),root); // Build(Key_value,0,tot-1,ch[root][1]); NewNode(Key_value,ch[root][1],tmp); Push_Up(ch[root][1]); Push_Up(root);}void erase(int r){ if(r) { s[++tot2]=r; erase(ch[r][0]); erase(ch[r][1]); }}//从第pos个数开始连续删除tot个数void Delete(int pos,int tot){ Splay(Get_Kth(root,pos),0); Splay(Get_Kth(root,pos+tot+1),root); erase(Key_value); // s[++tot2]=Key_value; pre[Key_value]=0; Key_value=0; Push_Up(ch[root][1]); Push_Up(root);}//从第pos个数连续开始的tot个数修改为c=>增加cvoid Make_Same(int pos,int tot,int c){ Splay(Get_Kth(root,pos),0); Splay(Get_Kth(root,pos+tot+1),root); Update_Same(Key_value,c); Push_Up(ch[root][1]); Push_Up(root);}//反转void Reverse(int pos,int tot){ Splay(Get_Kth(root,pos),0); Splay(Get_Kth(root,pos+tot+1),root); Update_Rev(Key_value); Push_Up(ch[root][1]); Push_Up(root);}//求和=>求最小值int Get_Sum(int pos,int tot){ Splay(Get_Kth(root,pos),0); Splay(Get_Kth(root,pos+tot+1),root); return sum[Key_value];}void revolve(int l,int r,int T){// Splay(Get_Kth(root,pos),0);// Splay(Get_Kth(root,pos+tot+1),root);// int tmp=Key_value;// Key_value=0;// Push_Up(ch[root][1]);// Push_Up(root);// Splay(Get_Kth(root,pos1+1),0);// Splay(Get_Kth(root,pos1+2),root);// Key_value=tmp;// pre[Key_value]=ch[root][1];// Push_Up(ch[root][1]);// Push_Up(root); int len=r-l+1; T=(T%len+len)%len; if(T==0)return; int c=r-T+1;//将区间[c,r]放在[l,c-1]前面 Splay(Get_Kth(root,c),0); Splay(Get_Kth(root,r+2),root); int tmp=Key_value; Key_value=0; Push_Up(ch[root][1]); Push_Up(root); Splay(Get_Kth(root,l),0); Splay(Get_Kth(root,l+1),root); Key_value=tmp; pre[Key_value]=ch[root][1];//这个不用忘记 Push_Up(ch[root][1]); Push_Up(root);}void Inorder(int r){ if(!r)return; Push_Down(r); Inorder(ch[r][0]); printf("%d ",sum[r]); Inorder(ch[r][1]);}int main(){ // freopen("cin.txt","r",stdin); //freopen("out.txt","w",stdout); while(~scanf("%d",&n)) { Init(); char op[20]; int x,y,z; scanf("%d",&q); while(q--) { scanf("%s",op); if(strcmp(op,"INSERT")==0) { scanf("%d%d",&x,&y); Insert(x,1,y); } else if(strcmp(op,"DELETE")==0) { scanf("%d%d",&x); Delete(x,1); } else if(strcmp(op,"ADD")==0) { scanf("%d%d%d",&x,&y,&z); Make_Same(x,y-x+1,z); } else if(strcmp(op,"REVERSE")==0) { scanf("%d%d",&x,&y); Reverse(x,y-x+1); } else if(op[0]=='M') { scanf("%d%d",&x,&y); printf("%d\n",Get_Sum(x,y-x+1)); } else if(strcmp(op,"REVOLVE")==0) { scanf("%d%d%d",&x,&y,&z); // z=z%(y-x+1); // if(z==0) continue; int a=y-z+1,b=y,c=x; revolve(x,y,z); } } //Inorder(root); } return 0;}
- poj3580supermemo【splay】
- poj3580SuperMemo(splay丰富的操作)
- SPLAY
- splay
- splay
- splay
- Splay
- Splay
- splay
- splay
- splay
- splay
- Splay
- splay
- Splay
- splay
- Splay
- Splay
- Python学习笔记09
- 菜鸟学python(11)list列表基本操作
- EasyUI-Datagrid二维表格:多表头
- Problem D: 删出多余的空格
- win7 64 位 ipython及notebook的安装
- poj3580supermemo【splay】
- java基础(21)--序列化简单例子
- redis -key的定义规则
- Atom和Webstorm开发环境搭建
- SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
- API 升级
- python编解码的那些事儿
- 初步了解响应式框架——agera
- Android控件篇之视图控件scrollview探索