博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
po3580SuperMemo(splay)
阅读量:4701 次
发布时间:2019-06-09

本文共 5237 字,大约阅读时间需要 17 分钟。

操作不少,不过都是一些基本的操作,增删,旋转,逆转,询问最小。

注意一点:T<0时 让t=0;

旋转的时候,是顺时针旋转,数据范围在int内。

刚开始旋转转错方向了。。

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 using namespace std; 11 #define N 200010 12 #define LL long long 13 #define INF 0xfffffff 14 #define key_value ch[ch[root][1]][0] 15 const double eps = 1e-8; 16 const double pi = acos(-1.0); 17 const double inf = ~0u>>2; 18 using namespace std; 19 int a[N]; 20 struct splay_tree 21 { 22 int pre[N],size[N]; 23 int ch[N][2]; 24 int root,tot; 25 int lz2[N]; 26 LL s[N],lz1[N],key[N]; 27 // void dfs(int x) 28 // { 29 // if(x) 30 // { 31 // dfs(ch[x][0]); 32 // printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size=%2d,key=%2d lz1 = %d lz2 = %d min = %d\n", 33 // x,ch[x][0],ch[x][1],pre[x],size[x],key[x],lz1[x],lz2[x],s[x]); 34 // dfs(ch[x][1]); 35 // } 36 // } 37 // void debug() 38 // { 39 // printf("root:%d\n",root); 40 // dfs(root); 41 // } 42 //以上用于debug*/ 43 void newnode(int &x,int v,int fa)//新建一结点 44 { 45 x = ++tot; 46 ch[x][0]=ch[x][1] = 0; 47 pre[x] = fa; 48 lz1[x] = lz2[x] = 0; 49 size[x] = 1; 50 s[x] = v; 51 key[x] = v; 52 } 53 void pushdown(int w) 54 { 55 int l = ch[w][0],r = ch[w][1]; 56 if(lz1[w]) 57 { 58 lz1[l] += lz1[w]; 59 lz1[r] += lz1[w]; 60 s[l]+=lz1[w]; 61 s[r]+=lz1[w]; 62 key[l]+=lz1[w]; 63 key[r]+=lz1[w]; 64 lz1[w] = 0; 65 } 66 if(lz2[w]) 67 { 68 lz2[l]^=lz2[w]; 69 lz2[r]^=lz2[w]; 70 swap(ch[w][0],ch[w][1]); 71 lz2[w] = 0; 72 } 73 } 74 void pushup(int w) 75 { 76 size[w] = size[ch[w][0]]+size[ch[w][1]]+1; 77 s[w] = key[w]; 78 if(ch[w][0]) 79 s[w] = min(s[w],s[ch[w][0]]); 80 if(ch[w][1]) 81 s[w] = min(s[w],s[ch[w][1]]); 82 } 83 void rotate(int r,int kind) 84 { 85 int y = pre[r]; 86 pushdown(y); 87 pushdown(r); 88 ch[y][!kind] = ch[r][kind]; 89 pre[ch[r][kind]] = y; 90 if(pre[y]) 91 { 92 ch[pre[y]][ch[pre[y]][1]==y] = r; 93 } 94 pre[r] = pre[y]; 95 ch[r][kind] = y; 96 pre[y] = r; 97 pushup(y); 98 pushup(r); 99 }100 void splay(int r,int goal)101 {102 pushdown(r);103 while(pre[r]!=goal)104 {105 if(pre[pre[r]]==goal)106 {107 rotate(r,ch[pre[r]][0]==r);108 }109 else110 {111 int y = pre[r];112 int kind = (ch[pre[y]][0]==y);113 if(ch[y][kind]==r)114 {115 rotate(r,!kind);116 rotate(r,kind);117 }118 else119 {120 rotate(y,kind);121 rotate(r,kind);122 }123 }124 }125 pushup(r);126 if(goal==0) root = r;127 }128 int get_k(int k)129 {130 int r = root;131 pushdown(r);132 while(size[ch[r][0]]+1!=k)133 {134 if(size[ch[r][0]]>=k)135 r = ch[r][0];136 else137 {138 k-=(size[ch[r][0]]+1);139 r = ch[r][1];140 }141 pushdown(r);142 }143 return r;144 }145 void add(int l,int r,int k)146 {147 splay(get_k(l),0);148 splay(get_k(r+2),root);149 lz1[key_value]+=k;150 s[key_value]+=k;151 key[key_value]+=k;152 pushup(ch[root][1]);153 pushup(root);154 }155 LL query(int l,int r)156 {157 splay(get_k(l),0);158 splay(get_k(r+2),root);159 return s[key_value];160 }161 void reverse(int l,int r)162 {163 splay(get_k(l),0);164 splay(get_k(r+2),root);165 lz2[key_value]^=1;166 pushup(ch[root][1]);167 pushup(root);168 }169 void revolve(int l,int r,int k)170 {171 splay(get_k(r-k+1),0);172 splay(get_k(r+2),root);173 int nod = key_value;174 key_value = 0;175 pushup(ch[root][1]);176 pushup(root);177 178 splay(get_k(l),0);179 splay(get_k(l+1),root);180 key_value = nod;181 pre[nod] = ch[root][1];182 pushup(ch[root][1]);183 pushup(root);184 }185 void insert(int k,int p)186 {187 splay(get_k(k),0);188 splay(get_k(k+1),root);189 newnode(key_value,p,ch[root][1]);190 pushup(ch[root][1]);191 pushup(root);192 }193 void updelete(int k)194 {195 splay(get_k(k),0);196 splay(get_k(k+2),root);197 key_value = 0;198 pushup(ch[root][1]);199 pushup(root);200 }201 void build(int &x,int l,int r,int fa)202 {203 int m = (l+r)>>1;204 if(l>r) return ;205 newnode(x,a[m],fa);206 build(ch[x][0],l,m-1,x);207 build(ch[x][1],m+1,r,x);208 pushup(x);209 }210 void init(int o)211 {212 int i;213 for(i = 1; i <= o ; i++)214 scanf("%d",&a[i]);215 size[0] = ch[0][0] = ch[0][1] = key[0] = lz1[0] = lz2[0] = s[0] = 0;216 root = tot = 0;217 newnode(root,0,0);218 newnode(ch[root][1],0,root);219 build(ch[ch[root][1]][0],1,o,ch[root][1]);220 size[root] = 2;221 pushup(ch[root][1]);222 pushup(root);223 }224 // void work()225 // {226 // for(int i = 1; i <= size[root] ;i++)227 // cout<
<<" ";228 // puts("");229 // }230 } SP;231 int main()232 {233 int n,q,k,x,y;234 char sq[10];235 while(scanf("%d",&n)!=EOF)236 {237 SP.init(n);238 scanf("%d",&q);239 while(q--)240 {241 scanf("%s",sq);242 if(sq[0]=='A')243 {244 scanf("%d%d%d",&x,&y,&k);245 SP.add(x,y,k);246 }247 else if(strcmp(sq,"REVERSE")==0)248 {249 scanf("%d%d",&x,&y);250 SP.reverse(x,y);251 }252 else if(strcmp(sq,"REVOLVE")==0)253 {254 scanf("%d%d%d",&x,&y,&k);255 if(k<=0) continue;256 k = k%(y-x+1);257 SP.revolve(x,y,k);258 }259 else if(sq[0]=='I')260 {261 scanf("%d%d",&k,&x);262 SP.insert(k+1,x);263 }264 else if(sq[0]=='D')265 {266 scanf("%d",&k);267 SP.updelete(k);268 }269 else if(sq[0]=='M')270 {271 scanf("%d%d",&x,&y);272 printf("%d\n",SP.query(x,y));273 }274 //SP.work();275 }276 }277 return 0;278 }
View Code

 

转载于:https://www.cnblogs.com/shangyu/p/3796675.html

你可能感兴趣的文章
poj1338【丑数·DP】
查看>>
PAT乙级(Basic Level)练习题-NowCoder数列
查看>>
HTML5项目笔记4:使用Audio API设计绚丽的HTML5音乐播放器
查看>>
[小白知识记录]--浏览器打开一个新窗口记录
查看>>
C++ Prime:const的引用
查看>>
SVM
查看>>
Java中删除文件、删除目录及目录下所有文件
查看>>
MiCode108 猜数字
查看>>
在Eclipse中Attach Source
查看>>
<Unity项目框架相关>一
查看>>
Vim 基本命令入门
查看>>
Hadoop Hive概念学习系列之HDFS、Hive、MySQL、Sqoop之间的数据导入导出(强烈建议去看)...
查看>>
不走弯路,就是捷径
查看>>
函数的记忆
查看>>
Linux centos7安装Mongodb
查看>>
svn自动备份并上传到ftp
查看>>
uTenux-OS-Task再探
查看>>
git
查看>>
#备注贴# 关于Java保真压缩的问题
查看>>
程序员50题(JS版本)(五)
查看>>