日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

POJ 3580SuperMemo

發(fā)布時間:2023/12/16 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 POJ 3580SuperMemo 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目:http://poj.org/problem?id=3580

題意:對一個數(shù)列進(jìn)行如下操作

操作1:對區(qū)間內(nèi)加一個數(shù)

操作2:對區(qū)間內(nèi)進(jìn)行反轉(zhuǎn)

操作3:對區(qū)間內(nèi)進(jìn)行平移 例如:區(qū)間內(nèi)數(shù)為2 3 4,平移1次,則為 4 2 3

操作4:在x后插入一個數(shù)

操作5:刪除x

操作6:求區(qū)間內(nèi)最小值

?

操作1,2,4,5,6都是splay的基本操作

對于操作3 我們可以先對t進(jìn)行取模 然后將區(qū)間內(nèi)最后t個分離出來,再插入到區(qū)間頭部

要實現(xiàn)這個操作,我們只需要先splay將這t個數(shù)組成的子樹分離,之后再對原樹進(jìn)行splay,再把這個子樹插入到區(qū)間頭部的左子樹下就完成了

//找了好久錯,最后發(fā)現(xiàn)我把+=寫成了=

#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<vector> #include<queue> #include<stack> #include<map> #include<set> #define lson i<<1 #define rson i<<1|1 using namespace std; const int N=2e5+5; const int inf=0x3f3f3f3f; int f[N],ch[N][2],sz[N],key[N],rev[N],add[N],minn[N]; int a[N]; int root,tot; inline int get(int x) {return ch[f[x]][1]==x; } void update(int x) {if (x==0) return;sz[x]=1;if (ch[x][0]) sz[x]+=sz[ch[x][0]];if (ch[x][1]) sz[x]+=sz[ch[x][1]];minn[x]=key[x];if (ch[x][0]) minn[x]=min(minn[x],minn[ch[x][0]]);if (ch[x][1]) minn[x]=min(minn[x],minn[ch[x][1]]); } void pushdown(int x) {if (x==0) return;if (add[x]){if (ch[x][0]){int now=ch[x][0];minn[now]+=add[x];key[now]+=add[x];add[now]+=add[x];}if (ch[x][1]){int now=ch[x][1];minn[now]+=add[x];key[now]+=add[x];add[now]+=add[x];}add[x]=0;}if (rev[x]){if (ch[x][0]){int now=ch[x][0];rev[now]^=1;swap(ch[now][0],ch[now][1]);}if (ch[x][1]){int now=ch[x][1];rev[now]^=1;swap(ch[now][0],ch[now][1]);}rev[x]=0;} } void Rotate(int x) {pushdown(f[x]);pushdown(x);int fa=f[x],ff=f[fa],kind=get(x);ch[fa][kind]=ch[x][kind^1];f[ch[x][kind^1]]=fa;ch[x][kind^1]=fa;f[fa]=x;f[x]=ff;if (ff)ch[ff][ch[ff][1]==fa]=x;update(fa);update(x); } void splay(int x,int y) {for(int fa;(fa=f[x])!=y;Rotate(x))if (f[fa]!=y)Rotate((get(fa)==get(x))?fa:x);if (y==0) root=x; } int build(int l,int r,int fa) {if (l>r) return 0;int mid=(l+r)>>1;int now=++tot;f[now]=fa;key[now]=minn[now]=a[mid];rev[now]=add[now]=0;ch[now][0]=build(l,mid-1,now);ch[now][1]=build(mid+1,r,now);update(now);return now; } int Find(int x) {int now=root;while(1){pushdown(now);if (ch[now][0]&&sz[ch[now][0]]>=x)now=ch[now][0];else{x-=sz[ch[now][0]];if (x==1) return now;x--;now=ch[now][1];}} }void Treaval(int x) {if(x) {pushdown(x);Treaval(ch[x][0]);printf("結(jié)點%2d:左兒子 %2d 右兒子 %2d 父結(jié)點 %2d size = %2d ,key = %2d min=%2d \n",x,ch[x][0],ch[x][1],f[x],sz[x],key[x],minn[x]);Treaval(ch[x][1]);} } void debug() {printf("%d\n",root);Treaval(root);}int main() {int n,m;while(scanf("%d",&n)!=EOF){tot=0;a[1]=a[n+2]=inf;for(int i=1;i<=n;i++)scanf("%d",&a[i+1]);root=build(1,n+2,0);scanf("%d",&m);char s[20];int x,y,t;while(m--){scanf("%s",s);switch(s[0]){case 'A':{scanf("%d%d%d",&x,&y,&t);int aa=Find(x);int bb=Find(y+2);splay(aa,0);splay(bb,aa);int now=ch[ch[root][1]][0];key[now]+=t;minn[now]+=t;add[now]+=t;update(ch[root][1]);update(root);break;}case 'R':{if (s[3]=='E'){scanf("%d%d",&x,&y);int aa=Find(x);int bb=Find(y+2);splay(aa,0);splay(bb,aa);int now=ch[ch[root][1]][0];rev[now]^=1;swap(ch[now][0],ch[now][1]);}else{scanf("%d%d%d",&x,&y,&t);int len=y-x+1;t=(t%len+len)%len;if (t==0) break;int aa=Find(y-t+1);int bb=Find(y+2);splay(aa,0);splay(bb,aa);int tem=ch[ch[root][1]][0];ch[ch[root][1]][0]=0;update(ch[root][1]);update(root);aa=Find(x);bb=Find(x+1);splay(aa,0);splay(bb,aa);ch[ch[root][1]][0]=tem;f[tem]=ch[root][1];update(ch[root][1]);update(root);}break;}case 'I':{scanf("%d%d",&x,&t);int aa=Find(x+1);int bb=Find(x+2);splay(aa,0);splay(bb,aa);int now=++tot;ch[ch[root][1]][0]=now;f[now]=ch[root][1];key[now]=t;sz[now]=1;minn[now]=t;ch[now][0]=ch[now][1]=rev[now]=add[now]=0;update(ch[root][1]);update(root);break;}case 'D':{scanf("%d",&x);int aa=Find(x);int bb=Find(x+2);splay(aa,0);splay(bb,aa);ch[ch[root][1]][0]=0;update(ch[root][1]);update(root);break;}case 'M':{scanf("%d%d",&x,&y);int aa=Find(x);int bb=Find(y+2);splay(aa,0);splay(bb,aa);int now=ch[ch[root][1]][0];//debug();printf("%d\n",minn[now]);break;}}}}return 0; }

  

轉(zhuǎn)載于:https://www.cnblogs.com/bk-201/p/7417317.html

總結(jié)

以上是生活随笔為你收集整理的POJ 3580SuperMemo的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。