【集训第四天·继续刷题】之 lgh怒刚ypj
繼續(xù)水題,終于完全掌握了伸展樹了,好心痛QAQ。
1.codevs1343 蚱蜢
區(qū)間最大值查詢+單點(diǎn)移動(dòng)
最大值查詢維護(hù)一個(gè)mx數(shù)組就行,單點(diǎn)移動(dòng)么,先刪除在插入
CODE:
1 /* 2 PS: 比較max值時(shí),要寫成 mx[x]=max(a[x],max(mx[l],mx[r]));形式 3 且最好把mx[0]賦值為負(fù)無窮大 4 5 取max時(shí),注意初值問題 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){//旋轉(zhuǎn) 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){//轉(zhuǎn)化為根 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 書架
單點(diǎn)移動(dòng)+單點(diǎn)查詢
移動(dòng)還是一樣,先刪除再插入
查詢編號(hào)為S的書的上面目前有多少本書時(shí),把S調(diào)整至根節(jié)點(diǎn),輸出左邊兒子的元素個(gè)數(shù)即可
查詢從上面數(shù)起的第S本書的編號(hào),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 反轉(zhuǎn)卡片
簡單到爆,一直區(qū)間倒置直到第一個(gè)數(shù)==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游戲排名系統(tǒng)
cnm勞資這個(gè)題調(diào)了一個(gè)晚上。。。。淚流滿面,本來還可以多寫2個(gè)題的。
使用hash或者map建立映射,記錄某人是否已出現(xiàn),如果出現(xiàn)的話刪除再插入,否則直接插入
查詢玩家排名時(shí),直接查詢他的編號(hào),把編號(hào)調(diào)整至根節(jié)點(diǎn),輸出右邊兒子的元素個(gè)數(shù)
最坑比的就是輸出從第x位起排名前10位的人。。我先用的是查找函數(shù),直接查找排名第x+1,x+2……點(diǎn)的編號(hào)并輸出名字,然而效率及其低下,codevsTLE3組。后來美膩的張姐告訴我:把x~x+10區(qū)間調(diào)整至一個(gè)子樹上,然后中序遍歷,輸出。我TM真的是個(gè)智障。。
PS:注意建立兩個(gè)虛節(jié)點(diǎn)分別作為第一和倒數(shù)第一,來保證splay操作的正確性或者加上特殊的判斷處理,但特判有些麻煩
CODE:
1 //愚蠢的TLE :輸出一段連續(xù)的區(qū)間值時(shí),不要一個(gè)一個(gè)找每個(gè)數(shù)的位置(超級(jí)費(fèi)時(shí)間) 2 // 把那整個(gè)區(qū)間轉(zhuǎn)移到一棵子樹上,中序輸出 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吵架了,原因是我們想離開高二機(jī)房,他不準(zhǔn),lgh又不肯退步,于是造成了慘劇(開玩笑)。。后來ypj就一直教育他(期間再次提到了某位打游戲翻車的同學(xué)),搞得他心情很不好啊,于是他就開始擠兌ypj,我估計(jì)后來ypj也非常不高興。
其實(shí)這件事呢,我們是不占理的。首先是沒給ypj說一聲就想走,十分的不尊重,其二就是lgh可能被憤怒沖昏了頭腦,說話非常的沖,讓人聽了很不爽,交流方式確實(shí)有些問題。當(dāng)然ypj說話也有些問題,他非常的不善言辭(就是瞎幾把說話)。在我看來,和ypj吵并不值得,因?yàn)樗緛砭秃懿豢衫碛?#xff0c;思想跟我們完全脫節(jié)。以后遇到這種情況,我們最好就是不跟他說屁話,打代碼。他bb夠了自己就離開了,免得吵起來雙方都不爽。
?
今天ypj講了主席樹,我聽懂了思想,但具體代碼實(shí)現(xiàn)還有些懵逼,明天再看看。。
chair-man tree
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/wsy01/p/6650544.html
總結(jié)
以上是生活随笔為你收集整理的【集训第四天·继续刷题】之 lgh怒刚ypj的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【HDU4734】F(x) 数位DP
- 下一篇: BZOJ4076 : [Wf2014]M