继续水题,终于完全掌握了伸展树了,好心痛QAQ。

  1.codevs1343 蚱蜢

  区间最大值查询+单点移动

  最大值查询维护一个mx数组就行,单点移动么,先删除在插入

CODE:

 1 /*
 2 PS:  比较max值时,要写成 mx[x]=max(a[x],max(mx[l],mx[r]));形式
 3     且最好把mx[0]赋值为负无穷大
 4
 5 取max时,注意初值问题
 6
 7 */
 8
 9 #include<bits/stdc++.h>
10 #define N 100005
11 using namespace std;
12 int c[N][2],fa[N],a[N],size[N],mx[N],n,m,rt;
13 int read(){
14     char c;int f=1,x=0;c=getchar();
15     while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
16     while(c<='9'&&c>='0')x=x*10+c-'0',c=getchar();
17     return f*x;
18 }
19
20 void pushup(int x){
21     int l=c[x][0],r=c[x][1];
22     size[x]=size[l]+size[r]+1;
23     mx[x]=max(a[x],max(mx[l],mx[r]));
24 }
25
26 void rotate(int x,int &k){//旋转
27     int y=fa[x],z=fa[y],l,r;
28     l=(c[y][1]==x);r=l^1;
29     if(y==k)k=x;
30     else c[z][c[z][1]==y]=x;
31     fa[c[x][r]]=y;fa[y]=x;fa[x]=z;
32     c[y][l]=c[x][r];c[x][r]=y;
33     pushup(y);pushup(x);
34 }
35
36 void splay(int x,int &k){//转化为根
37     while(x!=k){
38         int y=fa[x],z=fa[y];
39         if(y!=k){
40             if(c[y][0]==x^c[z][0]==y)rotate(x,k);
41             else rotate(y,k);
42         }
43         rotate(x,k);
44     }
45 }
46
47 void build(int l,int r,int f){
48     if(l>r)return;
49     if(l==r){c[f][l>=f]=l;fa[l]=f;mx[l]=a[l];size[l]=1;return;}
50     int mid=(l+r)>>1;build(l,mid-1,mid);build(mid+1,r,mid);
51     pushup(mid);fa[mid]=f;c[f][mid>=f]=mid;
52 }
53
54 int find(int x,int k){
55     int l=c[x][0],r=c[x][1];
56     if(size[l]+1==k)return x;
57     if(size[l]>=k)return find(l,k);
58     return find(r,k-size[l]-1);
59 }
60
61 void query(int l,int r){
62     int x=find(rt,l),y=find(rt,r+2);
63     splay(x,rt);splay(y,c[x][1]);
64     printf("%d\n",mx[c[y][0]]);
65 }
66
67 void move(int l,int r){
68     int x=find(rt,l),y=find(rt,l+2);
69     splay(x,rt);splay(y,c[x][1]);
70     int now=c[y][0];fa[now]=0;
71     c[y][0]=0;pushup(y);pushup(x);
72     x=find(rt,r+1);y=find(rt,r+2);
73     splay(x,rt);splay(y,c[x][1]);
74     c[y][0]=now;fa[now]=y;
75     pushup(y);pushup(x);
76 }
77
78 int main(){
79     n=read();m=read();
80     a[1]=a[n+2]=-99999999;
81     for(int i=1;i<=n;i++)a[i+1]=read();
82     build(1,n+2,0);rt=(n+3)>>1;
83     while(m--){
84         printf("\n");
85         int l,r;char s[10];l=read();
86         scanf("%s",s);
87         if(s[0]=='D'){r=read()+l;query(l+1,r);move(l,r-1);}
88         else{r=l-read();query(r,l-1);move(l,r-1);}
89     /*    for(int i=2;i<=n+1;i++){
90             int dada=find(rt,i);
91             printf("%d ",a[dada]);
92         }*/
93     }
94     return 0;
95 }

View Code

  2.codevs1514 书架

  单点移动+单点查询

  移动还是一样,先删除再插入

  查询编号为S的书的上面目前有多少本书时,把S调整至根节点,输出左边儿子的元素个数即可

  查询从上面数起的第S本书的编号,find(S)即可。

CODE:

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4
 5 const int INF = 1e9 + 7;
 6 const int maxn = 80000 + 10;
 7
 8 int n, m, root;
 9 int ch[maxn][2], p[maxn], a[maxn], s[maxn], v[maxn], id[maxn];
10
11 void update(int k) {
12     s[k] = s[ch[k][0]] + s[ch[k][1]] + 1;
13 }
14
15 void rotate(int& px, int& x, int d) {
16     int t = ch[x][d]; ch[x][d] = px; ch[px][d^1] = t;
17     p[x] = p[px]; p[px] = x; p[t] = px; update(px); update(x); px = x;
18 }
19
20 void splay(int x, int& k) {
21     while(x != k) {
22         int y = p[x], z = p[y];
23         int d = ch[y][0] == x ? 0 : 1;
24         int d2 = ch[z][0] == y ? 0 : 1;
25         if(y != k) rotate(ch[z][d2], x, d^1); else rotate(k, x, d^1);
26     }
27 }
28
29 void build(int L, int R, int P, int d) {
30     if(L == R) { s[L] = 1; p[L] = P; ch[P][d] = L; return; }
31     int M = (L+R) >> 1;
32     p[M] = P; ch[P][d] = M;
33     if(M-1 >= L) build(L, M-1, M, 0);
34     if(R >= M+1) build(M+1, R, M, 1);
35     update(M);
36 }
37
38 int find(int k, int rank) {
39     int l = ch[k][0], r = ch[k][1];
40     if(s[l]+1 == rank) return k;
41     else if(s[l] >= rank) return find(l, rank);
42     else return find(r, rank-s[l]-1);
43 }
44
45 void remove(int k) {
46     int x, y, z;
47     x = find(root, k-1); y = find(root, k+1);
48     splay(x, root); splay(y, ch[x][1]);
49     z = ch[y][0]; ch[y][0] = 0; p[z] = s[z] = 0;
50     update(y); update(x);
51 }
52
53 void move(int k, int val)  {
54     int o = id[k], x, y, rank;
55     splay(o, root);
56     rank = s[ch[o][0]] + 1;
57     remove(rank);
58     if(val == INF) x = find(root, n), y = find(root, n+1);
59     else if(val == -INF) x = find(root, 1), y = find(root, 2);
60     else x = find(root, rank+val-1), y = find(root, rank+val);
61     splay(x, root); splay(y, ch[x][1]);
62     s[o] = 1; p[o] = y; ch[y][0] = o;
63     update(y); update(x);
64 }
65
66 int main() {
67     scanf("%d%d", &n, &m);
68     for(int i = 2; i <= n+1; i++) scanf("%d", &v[i]), id[v[i]] = i;
69     build(1, n+2, 0, 1);
70     root = (n+3) >> 1;
71
72     char cmd[10]; int S, T;
73     for(int i = 1; i <= m; i++) {
74         scanf("%s%d", cmd, &S);
75         switch(cmd[0]) {
76             case 'T': move(S, -INF); break;
77             case 'B': move(S, INF); break;
78             case 'I': scanf("%d", &T); move(S, T); break;
79             case 'A': splay(id[S], root); printf("%d\n", s[ch[id[S]][0]]-1); break;
80             case 'Q': printf("%d\n", v[find(root, S+1)]); break;
81         }
82     }
83     return 0;
84 }  

View Code

  3.codevs1743 反转卡片

  简单到爆,一直区间倒置直到第一个数==1为止

CODE:

 1 #include<bits/stdc++.h>
 2 #define N 300005
 3 using namespace std;
 4 int c[N][2],fa[N],a[N],v[N],size[N],rev[N],rt,n,m;
 5 int read(){
 6     char c;int f=1,x=0;c=getchar();
 7     while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
 8     while(c<='9'&&c>='0')x=x*10+c-'0',c=getchar();
 9     return f*x;
10 }
11
12 void update(int x){
13     int l=c[x][0],r=c[x][1];
14     size[x]=size[l]+size[r]+1;
15 }
16
17 void pushdown(int x){
18     if(rev[x]){
19         swap(c[x][0],c[x][1]);rev[x]=0;
20         if(c[x][0])rev[c[x][0]]^=1;
21         if(c[x][1])rev[c[x][1]]^=1;
22     }
23 }
24
25 void rotate(int x,int &k){
26     int y=fa[x],z=fa[y],l,r;
27     if(c[y][0]==x)l=0;else l=1;r=l^1;
28     if(y==k)k=x;
29     else c[z][c[z][1]==y]=x;
30     fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
31     c[y][l]=c[x][r];c[x][r]=y;
32     update(y);update(x);
33 }
34
35 void splay(int x,int &k){
36     while(x!=k){
37         int y=fa[x],z=fa[y];
38         if(y!=k){
39             if(c[y][0]==x^c[z][0]==y)rotate(x,k);
40             else rotate(y,k);
41         }
42         rotate(x,k);
43     }
44 }
45
46 void build(int l,int r,int f){
47     if(l>r)return;
48     if(l==r){
49         size[l]=1;fa[l]=f;
50         if(l>f)c[f][1]=l;
51         else c[f][0]=l;
52         v[l]=a[l];
53         return;
54     }
55     int mid=(l+r)>>1;v[mid]=a[mid];
56     build(l,mid-1,mid);build(mid+1,r,mid);
57     update(mid);fa[mid]=f;c[f][mid>f]=mid;
58 }
59
60 int find(int x,int k){
61     pushdown(x);
62     int l=c[x][0],r=c[x][1];
63     if(size[l]+1==k)return x;
64     if(size[l]+1>k)return find(l,k);
65     return find(r,k-1-size[l]);
66 }
67
68 void rever(int l,int r){
69     int x=find(rt,l),y=find(rt,r+2);
70     splay(x,rt);splay(y,c[x][1]);
71     rev[c[y][0]]^=1;
72 }
73
74 int main(){
75     n=read();
76     a[0]=a[n+2]=99999999;
77     for(int i=1;i<=n;i++)a[i+1]=read();
78     build(1,n+2,0);rt=(3+n)>>1;
79      int x,y,ans=0;
80     while(1){
81         y=find(rt,2);
82         x=v[y];
83         if(x==1||ans>100000)break;
84         else rever(1,x);
85         ans++;
86     }
87     printf("%d",ans>100000?-1:ans);
88     return 0;
89 }

View Code

  4.codevs1985 GameZ游戏排名系统

  cnm劳资这个题调了一个晚上。。。。泪流满面,本来还可以多写2个题的。

  使用hash或者map建立映射,记录某人是否已出现,如果出现的话删除再插入,否则直接插入

  查询玩家排名时,直接查询他的编号,把编号调整至根节点,输出右边儿子的元素个数

  最坑比的就是输出从第x位起排名前10位的人。。我先用的是查找函数,直接查找排名第x+1,x+2……点的编号并输出名字,然而效率及其低下,codevsTLE3组。后来美腻的张姐告诉我:把x~x+10区间调整至一个子树上,然后中序遍历,输出。我TM真的是个智障。。

  PS:注意建立两个虚节点分别作为第一和倒数第一,来保证splay操作的正确性或者加上特殊的判断处理,但特判有些麻烦

CODE:

  1 //愚蠢的TLE :输出一段连续的区间值时,不要一个一个找每个数的位置(超级费时间)
  2 //                                   把那整个区间转移到一棵子树上,中序输出
  3 #include<bits/stdc++.h>
  4 #define N 250005
  5 #define inf 2147483647
  6 using namespace std;
  7 int n,c[N][2],fa[N],val[N],size[N],tot,rt,t1,t2;
  8 char s[15];
  9 struct player{
 10     int sc;
 11     char na[15];
 12 }p[N];
 13 map<string,int>mp;
 14 int read(){
 15     char c;int f=1,x=0;c=getchar();
 16     while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
 17     while(c<='9'&&c>='0')x=x*10+c-'0',c=getchar();
 18     return f*x;
 19 }
 20
 21 void pushup(int x){
 22     int l=c[x][0],r=c[x][1];
 23     size[x]=size[l]+size[r]+1;
 24 }
 25
 26 void rotate(int x,int &k){
 27     int y=fa[x],z=fa[y],l,r;
 28     if(c[y][0]==x)l=0;else l=1;r=l^1;
 29     if(y==k)k=x;
 30     else c[z][c[z][1]==y]=x;
 31     fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
 32     c[y][l]=c[x][r];c[x][r]=y;
 33     pushup(y);pushup(x);
 34 }
 35
 36 void splay(int x,int &k){
 37     while(x!=k){
 38         int y=fa[x],z=fa[y];
 39         if(y!=k){
 40             if((c[y][0]==x)^(c[z][0]==y))rotate(x,k);
 41             else rotate(y,k);
 42         }
 43         rotate(x,k);
 44     }
 45 }
 46
 47 void insert(int v,int num){
 48     if(!rt){rt=num;val[num]=v;size[rt]=1;return;}
 49     int p=rt,z;
 50     while(p){
 51         size[p]++;z=p;
 52         if(val[p]<v)p=c[p][1];
 53         else p=c[p][0];
 54     }
 55     val[num]=v;c[z][v>val[z]]=num;
 56     fa[num]=z;size[num]=1;
 57     splay(num,rt);
 58 }
 59
 60 int find(int x,int k){
 61     int l=c[x][0],r=c[x][1];
 62     if(size[r]+1==k)return x;
 63     if(size[r]>=k)return find(r,k);
 64     return find(l,k-size[r]-1);
 65 }
 66
 67 int trans(){
 68     int i=0,x=0;
 69     while(s[i]){x=x*10+s[i]-'0';i++;}
 70     return x;
 71 }
 72
 73 void del(int x){
 74     splay(x,rt);
 75     int l=c[x][0],r=c[x][1];
 76     while(c[l][1])l=c[l][1];
 77     while(c[r][0])r=c[r][0];
 78     splay(l,rt);splay(r,c[l][1]);
 79     fa[c[r][0]]=0;c[r][0]=0;
 80     pushup(r);pushup(l);
 81 }
 82
 83 void print(int x){
 84     if(!x)return;
 85     print(c[x][1]);
 86     printf("%s ",p[x].na);
 87     print(c[x][0]);
 88 }
 89
 90 void find_name(int a){
 91     int b=min(a+11,tot);
 92     int x=find(rt,b),y=find(rt,a);
 93     splay(x,rt);splay(y,c[x][1]);
 94     pushup(y);pushup(x);
 95     print(c[y][0]);
 96     printf("\n");
 97 }
 98
 99 int main(){
100     n=read();
101     insert(inf,1);
102     insert(-1,2);
103     tot=2;
104     for(int i=1;i<=n;i++){
105         char ch;scanf(" %c",&ch);
106         if(ch=='+'){
107             scanf("%s",p[++tot].na);p[tot].sc=read();
108             if(mp[p[tot].na]){
109                 int ps=mp[p[tot].na];
110                 del(ps);
111                 p[ps].sc=p[tot].sc;
112                 insert(p[tot].sc,ps);
113                 tot--;
114             }
115             else {
116                 mp[p[tot].na]=tot;
117                 insert(p[tot].sc,tot);
118             }
119         }
120         else {
121             scanf("%s",s);
122             if(s[0]>='1'&&s[0]<='9'){
123                 int pos=trans();
124                 find_name(pos);
125             }
126             else{
127                 int ps=mp[s];
128                 splay(ps,rt);
129                 printf("%d\n",size[c[rt][1]]);
130             }
131         }
132
133     }
134     return 0;
135 }

View Code

  记录一件事情,今晚lgh和ypj吵架了,原因是我们想离开高二机房,他不准,lgh又不肯退步,于是造成了惨剧(开玩笑)。。后来ypj就一直教育他(期间再次提到了某位打游戏翻车的同学),搞得他心情很不好啊,于是他就开始挤兑ypj,我估计后来ypj也非常不高兴。

  其实这件事呢,我们是不占理的。首先是没给ypj说一声就想走,十分的不尊重,其二就是lgh可能被愤怒冲昏了头脑,说话非常的冲,让人听了很不爽,交流方式确实有些问题。当然ypj说话也有些问题,他非常的不善言辞(就是瞎几把说话)。在我看来,和ypj吵并不值得,因为他本来就很不可理喻,思想跟我们完全脱节。以后遇到这种情况,我们最好就是不跟他说屁话,打代码。他bb够了自己就离开了,免得吵起来双方都不爽。

  今天ypj讲了主席树,我听懂了思想,但具体代码实现还有些懵逼,明天再看看。。

      chair-man tree

  

  

转载于:https://www.cnblogs.com/wsy01/p/6650544.html

【集训第四天·继续刷题】之 lgh怒刚ypj相关推荐

  1. 备战金三银四软件测试面试刷题小程序,错过你会后悔的

    目录 前言 软件测试基础题目 数据库面试题 接口测试工具 华为软件测试面试题 Linux服务器 总结 前言 想年后找工作或者等金三银四跳槽涨薪的朋友们有福了,今天给大家推荐一个软件测试面试的刷题小程序 ...

  2. python二级题库 第四套 附刷题软件

    刷 题软件(模拟python二级考试) 操作题刷题软件 公众h:露露IT 回复:python二级 一.选择题 1. 描述数据库系统中全局数据逻辑结构.且为全体用户公共数据视图的是(). A. 概念模式 ...

  3. 金三银四必备软件测试刷题神器,刷完还怕面试不过吗?

    小编热衷于收集整理资源,记录踩坑到爬坑的过程.希望能把自己所学,实际工作中使用的技术.学习方法.心得及踩过的一些坑,记录下来.也希望想做软件测试的你一样,通过我的分享可以少走一些弯路,可以形成一套自己 ...

  4. 四 . LeetCode标签刷题——树/二叉树(一) 算法部分

    各种二叉树的介绍汇总: 二叉树:最多有两棵子树的树被称为二叉树 满二叉树:二叉树中所有非叶子结点的度都是2,且叶子结点都在同一层次上 完全二叉树:如果一个二叉树与满二叉树前m个节点的结构相同,这样的二 ...

  5. 自学编程推荐的11个学习及刷题网站

    初学编程,很多人会选择先自学,那么这时候选择适合自己的学习平台是特别关键的,今天小优就给大家整理了11个学习及刷题网站. 一起来收藏起来! 第一类:课程学习类网站 1.菜鸟教程 菜鸟教程是 @Runo ...

  6. 有什么适合大一计算机专业学生免费的刷题网站?

    我打算按照菜鸡-初级-进阶-大神的顺序给大家推荐刷题网站,通通可以白嫖,大家可以根据自己的需求选取合适的学♂习网站噢,绝对不亏! 菜菜子刷题网站 对于大一计算机专业的学生来说,怕的不是没有刷题网站,而 ...

  7. CSP-S集训刷题记录

    $ CSP.S $ 集训刷题记录: $ By~wcwcwch $ 一.字符串专题: 1. [模板]$ manacher $ 算法 模型: 求出字符串 $ S $ 中所有回文串的位置及长度. $ sol ...

  8. 计算机基础知识必刷,《2019年江苏专转本考试-计算机基础必刷题题库(第四章)》...

    <2019年江苏专转本考试-计算机基础必刷题题库(第四章)> 一.判断   共3题 (共计3分) 第1题: 计算机信息系统的特征之一是处理的数据量大,因此必须在内存中设置缓冲区,用以长期保 ...

  9. 简易四六级刷题网站(一键帮你对答案)

    做了一个简易四六级刷题网站,网站链接:https://yoyo-checknow.github.io/. 操作方法可以查看B站视频:https://www.bilibili.com/video/BV1 ...

最新文章

  1. Centos 安装Mongo DB
  2. mybatis generator eclipse插件的安装
  3. 分享一个centos不错的镜像库
  4. Docker for windows 10
  5. 停止Hadoop或HBase集群的脚本
  6. Eclipse 答疑:Eclipse 如何设置 Java 代码自动提示和自动补全?
  7. 没有绝对的技术,只有不停的创新
  8. 使用Jquery EasyUi常见问题解决方案
  9. 了解Hadoop数据类型,输入输出格式及用户如何自定义。
  10. 关于MAC的pkg和mpkg的分别
  11. 数据结构与算法分析Java版pdf
  12. 采购订单定价策略 超详细
  13. Docker容器内安装wkhtmltox用来html转pdf
  14. LIN雨量传感器:拆解最低配的传感器8U0955559
  15. 前端(JavaScript)------字符串
  16. 解决phpstorm运行很卡问题
  17. css如何添加模糊效果,css动态模糊效果
  18. 售前工程师与售后工程师
  19. 四、PL/SQL程序控制语句
  20. 学生id号码是什么意思_教育ID号是什么

热门文章

  1. 学会使用svn:externals
  2. 热烈欢呼:cnblogs.com博客园首页通过W3C验证
  3. redis RedisTemplate实现分布式锁
  4. 忘记虚拟机root密码的解决办法
  5. WebVie打开woffice文档
  6. 元数据交换绑定的秘密
  7. C#中Json字符串的各种应用类
  8. 保监会:《保险公司信息系统安全管理指引(试行)》
  9. sfdisk命令的使用技巧
  10. 2008R2 文件服务器迁移新招