zoukankan      html  css  js  c++  java
  • 洛谷P3960 [NOIP2017] 列队

    数据结构题还是挺好玩的

    注意到每次只变动三个点:(x,y),(x,m),(n,m),其他地方都是整块移动。

    可以开n+1个线段树,前n个存每行前m-1个人,最后一个存第m列的人。

    (x,y)位置的人出列时,抽出该位置的标号,加到第n+1个线段树的最后面去,抽出第n+1个线段树的第x个元素(即(x,m),加到第x个线段树的最后面去。

    ↑实现这一操作,可以记线段树的size,每次二分查询树上第k个元素即可确定位置。

    ↑当然树不可能全建出来,需要动态开点。尚未申请的结点,size直接用$ r-l+1 $计算。

     

    写到一半想到不需要专门抽出来,只需要记录该行到该位置为止抽出过a个数,找(x,y)时实际找(x,y+a)即可。可以开个vector什么的存新加到队伍最右边的人。

    这样的话更加方便&优美,而且可以用树状数组写,代码量也减小了。

    但是看着自己写了一大半的代码不舍得丢,还是强行按原计划敲完了。

     

    ————

    老年退役选手连NOIP题都做不来了。做这题成功遇到了数组开小,变量写混,初始化错误,输出错误等等问题,调了好久。

    不开心QAQ

    ————

      1 #include<iostream>
      2 #include<cstdio>
      3 #define LL long long
      4 using namespace std;
      5 const int mxn=800010;
      6 struct node{
      7     int sz,lc,rc;
      8     LL mk;
      9 }t[mxn<<3];
     10 int cnt=0,mod=0;
     11 int root[mxn];
     12 int n,N,m,Q;
     13 inline int getsz(int l,int r,int rt){
     14     if(rt)return t[rt].sz;
     15     return r-l+1;
     16 }
     17 void pushup(int l,int r,int rt){
     18     int tmp=0;
     19     int mid=(l+r)>>1;
     20     tmp+=getsz(l,mid,t[rt].lc);
     21     tmp+=getsz(mid+1,r,t[rt].rc);
     22     t[rt].sz=tmp;
     23     return;
     24 }
     25 int anspos;
     26 int query(int k,int l,int r,int &rt){
     27     if(!rt){
     28         rt=++cnt;
     29         t[rt].sz=r-l+1;
     30     }
     31     if(l==r){
     32         if(!t[rt].mk){//计算标号 
     33             if(mod==n+1)t[rt].mk=(LL)l*m;
     34             else t[rt].mk=(LL)(mod-1)*m+l;
     35         }
     36         anspos=l;
     37         return rt;
     38     }
     39     int mid=(l+r)>>1,tmp=getsz(l,mid,t[rt].lc);
     40     if(k<=tmp)
     41         return query(k,l,mid,t[rt].lc);
     42     else return query(k-tmp,mid+1,r,t[rt].rc);
     43 }
     44 void update(LL v,int p,int l,int r,int &rt){
     45     if(!rt){
     46         rt=++cnt;
     47         t[rt].sz=r-l+1;
     48     }
     49     if(l==r){
     50         t[rt].mk=v;
     51         if(!v){//del
     52             t[rt].sz=0;
     53         }
     54         else t[rt].sz=1;
     55         return;
     56     }
     57     int mid=(l+r)>>1;
     58     if(p<=mid)update(v,p,l,mid,t[rt].lc);
     59     else update(v,p,mid+1,r,t[rt].rc);
     60     pushup(l,r,rt);
     61     return;
     62 }
     63 void info(int l,int r,int rt){
     64     printf("  %d %d rt:%d sz:%d
    ",l,r,rt,getsz(l,r,rt));
     65     if(!rt)return;
     66     if(l==r)return;
     67     int mid=(l+r)>>1;
     68     info(l,mid,t[rt].lc);
     69     info(mid+1,r,t[rt].rc);
     70     return;
     71 }
     72 int main(){
     73 //    freopen("2017phalanx.in","r",stdin);
     74 //    freopen("2017phalanx.out","w",stdout);
     75     int i,j,x,y,tmp;
     76     LL tmp2;
     77     scanf("%d%d%d",&n,&m,&Q);
     78     N=max(max(n,m),Q)<<1;
     79     while(Q--){
     80         scanf("%d%d",&x,&y);
     81         if(y==m){
     82             mod=n+1;
     83             tmp=query(x,1,N,root[n+1]);
     84             tmp2=t[tmp].mk;
     85             printf("%lld
    ",t[tmp].mk);
     86             update(0,anspos,1,N,root[n+1]);
     87             tmp=query(n,1,N,root[n+1]);
     88             update(tmp2,anspos,1,N,root[n+1]);
     89         }
     90         else{
     91 //            printf("  in
    ");
     92             mod=x;
     93             tmp=query(y,1,N,root[x]);
     94             tmp2=t[tmp].mk;
     95             printf("%lld
    ",t[tmp].mk);
     96             update(0,anspos,1,N,root[x]);//出队 
     97 //            printf("anspos:%d
    ",anspos);
     98             //
     99             mod=n+1;
    100             tmp=query(n+1,1,N,root[n+1]);
    101             update(tmp2,anspos,1,N,root[n+1]);
    102 //            printf("UPD: mk:%d pos:%d
    ",tmp2,anspos);
    103             //
    104             tmp=query(x,1,N,root[n+1]);
    105             tmp2=t[tmp].mk;
    106 //            printf("bu:%d anspos:%d
    ",tmp2,anspos);
    107             update(0,anspos,1,N,root[n+1]);
    108             mod=x;
    109             tmp=query(m-1,1,N,root[x]);
    110             update(tmp2,anspos,1,N,root[x]);
    111             //
    112         }
    113 //        info(1,N,root[n+1]);
    114     }
    115     return 0;
    116 }
  • 相关阅读:
    java前三章总结
    Java入门第二章
    java编程入门小结
    Java入门第二章
    java预习易错点
    计算机基础
    切换卡
    ajax
    水印4
    shuiyin3
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/9211075.html
Copyright © 2011-2022 走看看