暑期集训第六天(6-27)自由复习的题目练习及总结
Posted li-jia-hao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了暑期集训第六天(6-27)自由复习的题目练习及总结相关的知识,希望对你有一定的参考价值。
今天时间本来是很充裕的,毕竟不考试留出了一天的时间进行整理,直到我发现我打完替罪羊树编译报错一大堆(往上滑都要十多秒的那种),还没有调试就已经10点多快十一点的那一刻......郭大佬还是你郭大佬,后来我问他他说这道题他就写了一个多不到两个小时就过了......而我直到现在都还没调完,上午写完后心态直接爆炸,就去做其他的题了,下午又调了将近一个小时,只得了三分之一的分数,持续烦躁,就和后排的三个大神一起去水洛谷了,以后每天抽大概一个小时调一调,最好再重新写一遍吧,毕竟郭大佬也是写了一遍,重构了一遍(话说今天洛谷说我不宜重构代码???),我先把我的一上午的辛苦成果放在这吧,有大佬帮我调一调,纠纠错当然更好.
1 #include<bits/stdc++.h> 2 const int N=1e5+10; 3 struct Tree{ 4 int l,r,x,tot,siz,yxsiz,gssiz,fa; 5 //yx-有效 gs-个数 6 bool del; 7 }tree[N]; 8 double balance=0.75; 9 int len,shan[N],t,root; 10 int newp(){ 11 if(t>0) return shan[t--]; 12 return ++len; 13 } 14 void build(int x,int y,int fa){ 15 tree[y].x=x;tree[y].l=tree[y].r=0;tree[y].tot=1; 16 tree[y].del=false;tree[y].fa=fa; 17 tree[y].siz=tree[y].yxsiz=tree[y].gssiz=1; 18 } 19 int find(int x,int root){ 20 if(x<tree[root].x&&tree[root].l) return find(x,tree[root].l); 21 if(x>tree[root].x&&tree[root].r) return find(x,tree[root].r); 22 return root; 23 } 24 void update(int now,int x,int y,int z){ 25 if(!now) return; 26 tree[now].siz+=x; 27 tree[now].yxsiz+=y; 28 tree[now].gssiz+=z; 29 update(tree[now].fa,x,y,z); 30 } 31 struct Node{ 32 int x,tot; 33 }num[N]; 34 int num_tot=0; 35 void dfs_rebuild(int x) 36 { 37 if(x==0) return; 38 dfs_rebuild(tree[x].l); 39 if(!tree[x].del)num[++num_tot].x=tree[x].x,num[num_tot].tot=tree[x].tot; 40 shan[++t]=x; 41 dfs_rebuild(tree[x].r); 42 } 43 int readd(int l,int r,int fa){ 44 if(l>r) return 0; 45 int mid=(l+r)>>1;int id=newp(); 46 tree[id].fa=fa; 47 tree[id].tot=num[mid].tot; 48 tree[id].x=num[mid].x; 49 tree[id].l=readd(l,mid-1,id); 50 tree[id].r=readd(mid+1,r,id); 51 tree[id].gssiz=tree[tree[id].l].gssiz+tree[tree[id].r].gssiz+num[mid].tot; 52 tree[id].siz=tree[id].yxsiz=r-l+1; 53 tree[id].del=false; 54 return id; 55 } 56 void rebuild(int x){ 57 num_tot=0; 58 dfs_rebuild(x); 59 if(x==root) root=readd(1,num_tot,0); 60 else{ 61 update(tree[x].fa,-tree[x].siz+tree[x].yxsiz,0,0); 62 if(tree[tree[x].fa].l==x) tree[tree[x].fa].l=readd(1,num_tot,tree[x].fa); 63 else tree[tree[x].fa].r=readd(1,num_tot,tree[x].fa); 64 } 65 } 66 void find_rebuild(int now,int x){ 67 if((double)tree[tree[now].l].siz>(double)tree[now].siz*balance || 68 (double)tree[tree[now].r].siz>(double)tree[now].siz*balance || 69 (double)(tree[now].siz-(double)tree[now].yxsiz)>(double)tree[now].siz * 0.4){ 70 rebuild(now);return; 71 } 72 if(tree[now].x!=x) find_rebuild(x<tree[now].x ? tree[now].l : tree[now].r,x); 73 } 74 void Add(int x){ 75 if(root==0){ 76 build(x,root=newp(),0); 77 return; 78 } 79 int p=find(x,root); 80 if(tree[p].x==x){ 81 tree[p].tot++; 82 if(tree[p].del) tree[p].del=0,update(p,0,1,1); 83 else update(p,0,0,1); 84 } 85 else if(x<tree[p].x){ 86 build(x,tree[p].l=newp(),p);update(p,1,1,1); 87 } 88 else build(x,tree[p].r=newp(),p),update(p,1,1,1); 89 find_rebuild(root,x); 90 } 91 void del(int x){ 92 int p=find(x,root); 93 tree[p].tot--; 94 if(!tree[p].tot){ 95 tree[p].del=1; 96 update(p,0,-1,-1); 97 } 98 else update(p,0,0,-1); 99 find_rebuild(root,x); 100 } 101 void query_rank(int x){// 102 int now=root; 103 int ans=0; 104 while(tree[now].x!=x){ 105 if(x>=tree[now].x){ 106 ans+=tree[tree[now].l].gssiz+tree[now].tot; 107 now=tree[now].r; 108 } 109 else{ 110 now=tree[now].l; 111 } 112 } 113 ans+=tree[tree[now].l].yxsiz; 114 printf("%d ",ans+1); 115 } 116 void query_num(int rank){ 117 int now=root; 118 while(1){ 119 if(rank<=tree[tree[now].l].gssiz) now=tree[now].l; 120 else{ 121 rank-=tree[tree[now].l].gssiz; 122 if(rank<=tree[now].tot){ 123 printf("%d ",tree[now].x); 124 return; 125 } 126 rank-=tree[now].tot;now=tree[now].r; 127 } 128 } 129 } 130 bool ans=0; 131 void dfs_lson(int x){ 132 if(tree[x].r!=0) dfs_lson(tree[x].r); 133 if(ans) return; 134 if(!tree[x].del){ 135 ans=1; 136 printf("%d ",tree[x].x); 137 return; 138 } 139 if(tree[x].l!=0) dfs_lson(tree[x].l); 140 } 141 void dfs_rson(int x){ 142 if(tree[x].l!=0) dfs_rson(tree[x].l); 143 if(ans) return; 144 if(!tree[x].del){ 145 ans=1; 146 printf("%d ",tree[x].x); 147 return; 148 } 149 if(tree[x].r!=0) dfs_rson(tree[x].r); 150 } 151 void query_front(int now,int x,bool lson){ 152 if(!lson){ 153 query_front(tree[now].fa,x,tree[tree[now].fa].l==now); 154 return; 155 } 156 if(!tree[now].del&&tree[now].x<x){ 157 printf("%d ",tree[now].x); 158 return; 159 } 160 if(tree[now].l){ 161 ans=0; 162 dfs_lson(tree[now].l); 163 return; 164 } 165 query_front(tree[now].fa,x,tree[tree[now].fa].l==now); 166 } 167 void query_back(int now,int x,bool rson){ 168 if(!rson){ 169 query_back(tree[now].fa,x,tree[tree[now].fa].r==now); 170 return; 171 } 172 if(!tree[now].del&&tree[now].x>x){ 173 printf("%d ",tree[now].x); 174 return; 175 } 176 if(tree[now].r){ 177 ans=0; 178 dfs_rson(tree[now].r); 179 return; 180 } 181 query_back(tree[now].fa,x,tree[tree[now].fa].r==now); 182 } 183 int main(){ 184 //freopen("a.in","r",stdin); 185 int n; 186 scanf("%d",&n); 187 while(n--){ 188 int x,y; 189 scanf("%d%d",&x,&y); 190 if(x==1) Add(y); 191 if(x==2) del(y); 192 if(x==3) query_rank(y); 193 if(x==4) query_num(y); 194 if(x==5) query_front(find(y,root),y,true); 195 if(x==6) query_back(find(y,root),y,true); 196 } 197 return 0; 198 }
(这么彩的结果,你值得拥有)
先放一下这棵树来说一下今天的练习题吧.
看到这个题的第一感觉就是这道题建好图就已经成功了一大半了(某邹姓少年除外,他因为手懒用的STL的栈写的tarjan后来他自己都调不过,后来还是lc大佬调好的)最暴力的建图方式当然是枚举每一个兴奋值在兴趣值之中找到其倍数,之后连边,但是n最大到1e5,n^2的时间效率可能让我们的程序都活不到tarjan部分就挂了,我最先想到的思路是分别枚举兴趣值和兴奋值之中的约数和乘数,如果可以连在约数上的边一定
以上是关于暑期集训第六天(6-27)自由复习的题目练习及总结的主要内容,如果未能解决你的问题,请参考以下文章