【集训第四天·继续刷题】之 lgh怒刚ypj
继续水题,终于完全掌握了伸展树了,好心痛QAQ。
1.codevs1343 蚱蜢
区间最大值查询+单点移动
最大值查询维护一个mx数组就行,单点移动么,先删除在插入
CODE:
![](/assets/blank.gif)
![](/assets/blank.gif)
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:
![](/assets/blank.gif)
![](/assets/blank.gif)
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:
![](/assets/blank.gif)
![](/assets/blank.gif)
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:
![](/assets/blank.gif)
![](/assets/blank.gif)
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相关推荐
- 备战金三银四软件测试面试刷题小程序,错过你会后悔的
目录 前言 软件测试基础题目 数据库面试题 接口测试工具 华为软件测试面试题 Linux服务器 总结 前言 想年后找工作或者等金三银四跳槽涨薪的朋友们有福了,今天给大家推荐一个软件测试面试的刷题小程序 ...
- python二级题库 第四套 附刷题软件
刷 题软件(模拟python二级考试) 操作题刷题软件 公众h:露露IT 回复:python二级 一.选择题 1. 描述数据库系统中全局数据逻辑结构.且为全体用户公共数据视图的是(). A. 概念模式 ...
- 金三银四必备软件测试刷题神器,刷完还怕面试不过吗?
小编热衷于收集整理资源,记录踩坑到爬坑的过程.希望能把自己所学,实际工作中使用的技术.学习方法.心得及踩过的一些坑,记录下来.也希望想做软件测试的你一样,通过我的分享可以少走一些弯路,可以形成一套自己 ...
- 四 . LeetCode标签刷题——树/二叉树(一) 算法部分
各种二叉树的介绍汇总: 二叉树:最多有两棵子树的树被称为二叉树 满二叉树:二叉树中所有非叶子结点的度都是2,且叶子结点都在同一层次上 完全二叉树:如果一个二叉树与满二叉树前m个节点的结构相同,这样的二 ...
- 自学编程推荐的11个学习及刷题网站
初学编程,很多人会选择先自学,那么这时候选择适合自己的学习平台是特别关键的,今天小优就给大家整理了11个学习及刷题网站. 一起来收藏起来! 第一类:课程学习类网站 1.菜鸟教程 菜鸟教程是 @Runo ...
- 有什么适合大一计算机专业学生免费的刷题网站?
我打算按照菜鸡-初级-进阶-大神的顺序给大家推荐刷题网站,通通可以白嫖,大家可以根据自己的需求选取合适的学♂习网站噢,绝对不亏! 菜菜子刷题网站 对于大一计算机专业的学生来说,怕的不是没有刷题网站,而 ...
- CSP-S集训刷题记录
$ CSP.S $ 集训刷题记录: $ By~wcwcwch $ 一.字符串专题: 1. [模板]$ manacher $ 算法 模型: 求出字符串 $ S $ 中所有回文串的位置及长度. $ sol ...
- 计算机基础知识必刷,《2019年江苏专转本考试-计算机基础必刷题题库(第四章)》...
<2019年江苏专转本考试-计算机基础必刷题题库(第四章)> 一.判断 共3题 (共计3分) 第1题: 计算机信息系统的特征之一是处理的数据量大,因此必须在内存中设置缓冲区,用以长期保 ...
- 简易四六级刷题网站(一键帮你对答案)
做了一个简易四六级刷题网站,网站链接:https://yoyo-checknow.github.io/. 操作方法可以查看B站视频:https://www.bilibili.com/video/BV1 ...
最新文章
- Centos 安装Mongo DB
- mybatis generator eclipse插件的安装
- 分享一个centos不错的镜像库
- Docker for windows 10
- 停止Hadoop或HBase集群的脚本
- Eclipse 答疑:Eclipse 如何设置 Java 代码自动提示和自动补全?
- 没有绝对的技术,只有不停的创新
- 使用Jquery EasyUi常见问题解决方案
- 了解Hadoop数据类型,输入输出格式及用户如何自定义。
- 关于MAC的pkg和mpkg的分别
- 数据结构与算法分析Java版pdf
- 采购订单定价策略 超详细
- Docker容器内安装wkhtmltox用来html转pdf
- LIN雨量传感器:拆解最低配的传感器8U0955559
- 前端(JavaScript)------字符串
- 解决phpstorm运行很卡问题
- css如何添加模糊效果,css动态模糊效果
- 售前工程师与售后工程师
- 四、PL/SQL程序控制语句
- 学生id号码是什么意思_教育ID号是什么