zoukankan      html  css  js  c++  java
  • bzoj3600: 没有人的算术

    题意:太难说了。。手动去看吧反正不是权限题。

    膜拜VFK大爷的神题!

    其实一开始思路挺清楚的,如果我们能做到用一个实数去代表“数”,这就是裸的动态区间最值查询。

    关键是怎么用实数去表示。如果我们单纯的把两个数进行O(1)运算去得到一个实数,这样很轻松就会被卡掉,因为无论是longlong还是double都是有限度的。怎么做呢?

    这里有一个技巧:我们维护一个重量平衡树,每个节点管辖一个区间,这个区间的中位数为这个点的权值,而它的左儿子管辖左半边,右儿子管辖右半边。

    问题来了,这不是差不多吗?并不是这样。因为我们会重构,树高有保证,所以我们肯定能表示出每一个数,而且还是绰绰有余。

    重量平衡树可以用不旋转的treap或替罪羊树。

    (吐槽一句,第一次写替罪羊树,真的好TM难写啊还套了个线段树而且我常数大的飞起,写了一整天)

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define N 500005
      4 #define LL long long
      5 inline LL read(){
      6     LL x=0,f=1; char a=getchar();
      7     while(a<'0' || a>'9') {if(a=='-') f=-1; a=getchar();}
      8     while(a>='0' && a<='9') x=x*10+a-'0',a=getchar();
      9     return x*f;
     10 }
     11 int n,m; char st[5];
     12 LL MX;
     13 #define SGT Scapegoat_Tree
     14 #define ST Segment_Tree
     15 
     16 namespace Scapegoat_Tree{
     17     #define eps 1e-12
     18     const double alpha=0.75;
     19     int ltst,wh,size=1,tmp[N],root=1,anew;
     20     struct sgt{
     21         LL l,r,mid; int fir,sec;
     22         int son[2],sz;
     23     }tr[N];
     24     inline int dcmp(int x,int y){
     25         if(fabs((double)tr[x].sz*alpha-(double)tr[y].sz)<eps) return 0;
     26         else return (double)tr[x].sz*alpha>(double)tr[y].sz?1:-1;
     27     }
     28     inline void update(int x){
     29         tr[x].sz=tr[tr[x].son[0]].sz+tr[tr[x].son[1]].sz+1;
     30     }
     31     inline bool balance(int x){
     32         return dcmp(x,tr[x].son[0])>=0 && dcmp(x,tr[x].son[1])>=0;
     33     }
     34     void travel(int x){
     35         if(!x) return;
     36         travel(tr[x].son[0]);
     37         tmp[++tmp[0]]=x;
     38         travel(tr[x].son[1]);
     39     }
     40     void rebuild(int &x,int l,int r,LL L,LL R){
     41         if(l>r) {x=0; return;}
     42         int mid=(l+r)>>1;
     43         LL M=(L+R)/2;
     44         x=tmp[mid]; tr[x].l=L; tr[x].r=R; tr[x].mid=M;
     45         if(l==r) {tr[x].sz=1; tr[x].son[0]=0; tr[x].son[1]=0; return;}
     46         rebuild(tr[x].son[0],l,mid-1,L,M); rebuild(tr[x].son[1],mid+1,r,M,R);
     47         update(x);
     48     }
     49     void insert(int& x,LL L,LL R,int fir,int sec){
     50         if(!x) {x=++size; anew=x;tr[x]=(sgt){L,R,(L+R)/2,fir,sec,0,0,1}; return;}
     51         if(tr[tr[x].fir].mid==tr[fir].mid && tr[tr[x].sec].mid==tr[sec].mid) {anew=x; return;}
     52         else if(tr[tr[x].fir].mid==tr[fir].mid){
     53             if(tr[tr[x].sec].mid>tr[sec].mid) insert(tr[x].son[0],tr[x].l,tr[x].mid,fir,sec);
     54             else insert(tr[x].son[1],tr[x].mid,tr[x].r,fir,sec);
     55         }
     56         else{
     57             if(tr[tr[x].fir].mid>tr[fir].mid) insert(tr[x].son[0],tr[x].l,tr[x].mid,fir,sec);
     58             else insert(tr[x].son[1],tr[x].mid,tr[x].r,fir,sec);
     59         }
     60         update(x);
     61         if(tr[x].son[0] && !balance(tr[x].son[0])) ltst=x,wh=0;
     62         else if(tr[x].son[1] && !balance(tr[x].son[1])) ltst=x,wh=1;
     63         if(x==root && !balance(x)) tmp[0]=0,travel(root),rebuild(root,1,tmp[0],1,MX);
     64     }
     65 }
     66 namespace Segment_Tree{
     67     int a[N];
     68     struct seg{
     69         int l,r,son[2],mx_pos,num;         
     70     }tr[N];
     71     inline void update(int x){
     72         if(SGT::tr[tr[tr[tr[x].son[0]].mx_pos].num].mid==SGT::tr[tr[tr[tr[x].son[1]].mx_pos].num].mid){
     73             int le=tr[tr[x].son[0]].mx_pos,ri=tr[tr[x].son[1]].mx_pos;
     74             tr[x].mx_pos=tr[le].l<tr[ri].l?le:ri;
     75         }
     76         else if(SGT::tr[tr[tr[tr[x].son[0]].mx_pos].num].mid>SGT::tr[tr[tr[tr[x].son[1]].mx_pos].num].mid) 
     77         tr[x].mx_pos=tr[tr[x].son[0]].mx_pos;
     78         else tr[x].mx_pos=tr[tr[x].son[1]].mx_pos;
     79     }
     80     void build(int x,int l,int r){
     81         if(l==r) {tr[x]=(seg){l,r,0,0,x,1};return;}
     82         int mid=(l+r)>>1; tr[x].l=l; tr[x].r=r;
     83         tr[x].son[0]=x<<1; build(tr[x].son[0],l,mid);
     84         tr[x].son[1]=x<<1|1; build(tr[x].son[1],mid+1,r);
     85         update(x);
     86     }
     87     void modify(int x,int ai,int v){
     88         int l=tr[x].l,r=tr[x].r;
     89         if(l==r) {tr[x].num=v; return;}
     90         int mid=(l+r)>>1;
     91         if(ai<=mid) modify(tr[x].son[0],ai,v);
     92         else modify(tr[x].son[1],ai,v);
     93         update(x);
     94     }
     95     int query(int x,int L,int R){
     96         int l=tr[x].l,r=tr[x].r;
     97         if(l==L && r==R) return tr[x].mx_pos;
     98         int mid=(l+r)>>1;
     99         if(R<=mid) return query(tr[x].son[0],L,R);
    100         else if(mid<L) return query(tr[x].son[1],L,R);
    101         else{
    102             int le=query(tr[x].son[0],L,mid),ri=query(tr[x].son[1],mid+1,R);
    103             if(SGT::tr[tr[le].num].mid==SGT::tr[tr[ri].num].mid) return tr[le].l<tr[ri].l?le:ri;
    104             return SGT::tr[tr[le].num].mid>SGT::tr[tr[ri].num].mid?le:ri;
    105         }
    106     }
    107 }
    108 
    109 int main(){
    110     n=read(); m=read(); MX=1;
    111     for(int i=1;i<=60;i++) MX*=2;
    112     ST::build(1,1,n); SGT::tr[1]=(SGT::sgt){1,MX,(1+MX)/2,0,0,0,0,1};
    113     for(int i=1;i<=n;i++) ST::a[i]=1;
    114     while(m--){
    115         scanf("%s",st); int k,l=read(),r=read();
    116         if(st[0]=='C'){
    117             k=read(); 
    118             l=ST::a[l]; r=ST::a[r]; SGT::ltst=0; SGT::insert(SGT::root,1,MX,l,r);
    119             if(SGT::ltst) {
    120                 SGT::tmp[0]=0; SGT::travel(SGT::tr[SGT::ltst].son[SGT::wh]); 
    121                 LL L=SGT::tr[SGT::tr[SGT::ltst].son[SGT::wh]].l,R=SGT::tr[SGT::tr[SGT::ltst].son[SGT::wh]].r;
    122                 SGT::rebuild(SGT::tr[SGT::ltst].son[SGT::wh],1,SGT::tmp[0],L,R);
    123             }
    124             ST::modify(1,k,SGT::anew),ST::a[k]=SGT::anew;
    125         }else{
    126             int ans=ST::query(1,l,r);
    127             ans=ST::tr[ans].l;
    128             printf("%d
    ",ans);
    129         }
    130     }
    131     return 0;
    132 }
  • 相关阅读:
    hdu 1106 排序(排序)
    hdu 1040 As Easy As A+B(排序)
    hdu 1029 Ignatius and the Princess IV(排序)
    mysql-9索引
    mysql-8 alter命令
    mysql-7事务管理
    mysql-6正则表达式
    http协议
    9-2交互体验
    9-2专项测试下午
  • 原文地址:https://www.cnblogs.com/enigma-aw/p/6246955.html
Copyright © 2011-2022 走看看