zoukankan      html  css  js  c++  java
  • HDU多校2020 第九场 G-Game(fhq treap+维护区间移动

    题意:http://acm.hdu.edu.cn/showproblem.php?pid=6873

    推格子,和牛客多校2020某场操作几乎原模原样,只是询问更加细节

    思路:

    fhq treap,之前没学,学了之后就是那个min操作相关的split有点小妙其他一般般吧

      1 #define int ll
      2 int a[N];
      3 
      4 class TREAP
      5 {
      6 public:
      7     int tot;
      8     int tr[N][2],sz[N],val[N],rnd[N],min_[N],sum[N];
      9     void Init()
     10     {
     11         tot=0;
     12         min_[0]=inf;
     13     }
     14     int newnode(int x){
     15         ++tot;
     16         sz[tot]=1;
     17         sum[tot]=min_[tot]=val[tot]=x;
     18         tr[tot][0]=tr[tot][1]=0;
     19         rnd[tot]=rand_num()%mod;
     20         return tot;
     21     }
     22     void up(int rt){
     23         sz[rt]=1+sz[tr[rt][0]]+sz[tr[rt][1]];
     24         sum[rt]=val[rt]+sum[tr[rt][0]]+sum[tr[rt][1]];
     25         min_[rt]=min(val[rt],min(min_[tr[rt][0]],min_[tr[rt][1]]));
     26     }
     27     void split_by_sz(int now,int leftsz,int &x,int &y){
     28         if(!now){x=y=0;return;}
     29         if(leftsz<=sz[tr[now][0]])y=now,split_by_sz(tr[now][0],leftsz,x,tr[now][0]);
     30         else x=now,split_by_sz(tr[now][1],leftsz-sz[tr[now][0]]-1,tr[now][1],y);
     31         up(now);
     32     }
     33     void split_by_v(int now,int v,int &x,int &y){
     34         if(!now){x=y=0;return;}
     35         if(!(val[now]>=v&&min_[tr[now][1]]>=v))x=now,split_by_v(tr[now][1],v,tr[now][1],y);
     36         else y=now,split_by_v(tr[now][0],v,x,tr[now][0]);
     37         up(now);
     38     }
     39     int merge(int x,int y){//注意这个操作的返回值是根节点
     40         if(!x||!y)return x+y;//如果有一棵树是空的,返回另一棵树就可以
     41         if(rnd[x]<rnd[y]){//比较修正值
     42             tr[x][1]=merge(tr[x][1],y);//把y合并到x的右子树
     43             up(x);
     44             return x;
     45         }
     46         else{
     47             tr[y][0]=merge(x,tr[y][0]);//把x合并到y的左子树
     48             up(y);
     49             return y;
     50         }
     51     }
     52     void insert(int pos,int v,int &rt){
     53         int x,y;
     54         split_by_sz(rt, pos-1, x, y);
     55         rt = merge(merge(x ,newnode(v)), y);
     56     }
     57     int kth(int now,int k){
     58         if(k>sz[tr[now][0]]&&k<=sz[now]-sz[tr[now][1]])return val[now];
     59         if(k<=sz[tr[now][0]])return kth(tr[now][0],k);
     60         else return kth(tr[now][1],k-(sz[now]-sz[tr[now][1]]));
     61     }
     62     //===========================题目函数
     63     ll Lmove(int x,int y,int &rt)
     64     {
     65         if(kth(rt,x)<y)    return 0LL;
     66         int lls,rrs;
     67         int z,zz,x1,x2,x3,x4;
     68         split_by_sz(rt,x,lls,rrs);
     69         if(min_[lls]>=y)return rt=merge(lls,rrs),0LL;
     70         split_by_v(lls,y,z,zz);
     71         ll res=sum[zz]-1LL*(y-1)*sz[zz];
     72         split_by_sz(zz,1,x1,x2);
     73         int tmp=val[x1]-y+1,cnt=sz[z],cntx2=sz[x2];
     74         split_by_sz(z,cnt-1,x3,x4);
     75         int v4=val[x4]+tmp;
     76         rt=merge(merge(x3,x2),rrs);
     77         insert(cnt,v4,rt),insert(x,y-1,rt);
     78         return res;
     79     }
     80 }treap;
     81 
     82 void solve()
     83 {
     84     int n,m;
     85     FI(n),FI(m);
     86     treap.Init();
     87     int rt=0;
     88     for(int i=1;i<=n;++i)
     89     {
     90         FI(a[i]);
     91         treap.insert(i,a[i],rt);
     92     }
     93     for(int i=1;i<=m;++i)
     94     {
     95         int op,x,y;
     96         FI(op);
     97         if(op==1)
     98         {
     99             FI(x),FI(y);
    100             FO(treap.Lmove(x,y,rt));
    101             FO('
    ');
    102         }
    103         else
    104         {
    105             FI(x);
    106             FO(treap.kth(rt,x));
    107             FO('
    ');
    108         }
    109     }
    110     for(int i=1;i<=n;++i)
    111     {
    112         FO(treap.kth(rt,i));
    113         if(i==n)FO('
    ');
    114         else FO(' ');
    115     }
    116     Flush;
    117 }
    118 
    119 signed main()
    120 {
    121     int T;
    122     sc("%lld",&T);
    123     while(T--)solve();
    124     return 0;
    125 }
  • 相关阅读:
    由ping百度引发的思考
    操作系统 | 概述
    操作系统导论第四章 | 抽象:进程
    汇编语言 | 定制键盘输入的处理过程
    细数 TS 中那些奇怪的符号
    vue 各种 import 引入
    display:table-cell实现水平垂直居中
    Jquery判断单选框是否选中和获取选中的值
    css整理 -- 右箭头,上下箭头,三角形、超出省略号代替
    JQuery操作select下拉框
  • 原文地址:https://www.cnblogs.com/--HPY-7m/p/13529469.html
Copyright © 2011-2022 走看看