zoukankan      html  css  js  c++  java
  • 【集训第四天·继续刷题】之 lgh怒刚ypj

      继续水题,终于完全掌握了伸展树了,好心痛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
    ",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("
    ");
    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
    ", s[ch[id[S]][0]]-1); break;   
    80             case 'Q': printf("%d
    ", 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("
    ");
     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
    ",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

      

      










    If you live in the echo,
    your heart never beats as loud.
    如果你生活在回声里,
    你的心跳声永远不会轰鸣作响。
  • 相关阅读:
    Enterprise Library 企业库 V4.1
    跨域实现IFRAME自适应高度
    微软企业库4.1学习笔记(二)各功能之间的依赖关系以及对象创建
    微软企业库4.1学习笔记(三)企业库迁移和并行使用,以及企业库的扩展
    微软企业库4.1学习笔记(五)对象创建和依赖注入方法
    判断 iframe 是否加载完成的完美方法
    对JavaScript调用堆栈和setTimeout用法的深入研究
    工作流技术杂谈
    企业流程管理平台V2.0介绍(.NET平台下的工作流)
    c#操作oracle lob字段[转自 芽芽的回收站]
  • 原文地址:https://www.cnblogs.com/wsy01/p/6650544.html
Copyright © 2011-2022 走看看