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

    查询可以直接线段树维护,修改呢,考虑一颗替罪羊,每个点代表一段区间,他的$val$就是区间中值,线段树记录对应节点的$id$,再开一个数组记录即时的权值,因为重建时$val$可能会变。这好像是重量平衡树的应用,然而究竟什么是重量平衡树呢?

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<algorithm>
      5 #include<cmath>
      6 #define inf 0x3fffffffffffffff
      7 #define alp 0.75
      8 #define N 500050
      9 using namespace std;
     10 double a[500050];
     11 int tot;
     12 struct Node{
     13     Node *ch[2];
     14     double l,r;
     15     int size,cover,ex,k1,k2,id;
     16     void pushup(){
     17         size=ch[0]->size+ch[1]->size+ex;
     18         cover=ch[0]->cover+ch[1]->cover+1;
     19     }
     20     bool bad(){
     21         return ch[0]->cover>=cover*alp+5||ch[1]->cover>=cover*alp+5;
     22     }
     23     Node(double x,double y,int z,int w,int k);
     24 }*null=new Node(0,0,0,0,0),*root,*sta[N];
     25 int len;
     26 Node:: Node(double x,double y,int z,int w,int k){
     27     l=x;r=y;k1=z;k2=w;id=k;
     28     a[k]=(l+r)/2.0;
     29     size=cover=ex=1;
     30     ch[0]=ch[1]=null;
     31 }
     32 void init(){
     33     null->ch[0]=null->ch[1]=null;
     34     null->l=null->r=null->k1=null->k2=null->id=0;
     35     null->size=null->cover=null->ex=0;
     36     a[0]=-5000000000000000000;
     37     root=new Node(-inf,inf,0,0,++tot);
     38 }
     39 Node **insert(Node *&rt,double l,double r,int k1,int k2){
     40     if(rt==null){
     41         rt=new Node(l,r,k1,k2,++tot);
     42         return &null;
     43     }
     44     rt->size++;rt->cover++;
     45     Node **ret;
     46     if(a[rt->k1]<a[k1]||(a[rt->k1]==a[k1]&&a[rt->k2]<a[k2]))ret=insert(rt->ch[1],(rt->l+rt->r)/2.0,rt->r,k1,k2);
     47     else ret=insert(rt->ch[0],rt->l,(rt->l+rt->r)/2.0,k1,k2);
     48     if(rt->bad())ret=&rt;
     49     return ret;
     50 }
     51 void travel(Node *rt){
     52     if(rt==null)return;
     53     travel(rt->ch[0]);
     54     if(rt->ex){
     55         sta[++len]=rt;
     56         travel(rt->ch[1]);
     57     }
     58     else{
     59         travel(rt->ch[1]);
     60         delete rt;
     61     }
     62 }
     63 Node * divide(int l,int r,double L,double R){
     64     if(l>r)return null;
     65     int mid=(l+r)>>1;
     66     sta[mid]->l=L;sta[mid]->r=R;a[sta[mid]->id]=(L+R)/2.0;
     67     sta[mid]->ch[0]=divide(l,mid-1,L,(L+R)/2.0);
     68     sta[mid]->ch[1]=divide(mid+1,r,(L+R)/2.0,R);
     69     sta[mid]->pushup();
     70     return sta[mid];
     71 }
     72 void rebuild(Node *&rt){
     73     double L=rt->l,R=rt->r;
     74     len=0;travel(rt);
     75     rt=divide(1,len,L,R);
     76 }
     77 void insert(int k1,int k2){
     78     Node **p=insert(root,-inf,inf,k1,k2);
     79     if(*p!=null)rebuild(*p);
     80 }
     81 Node *find(Node *rt,int k1,int k2){
     82     if(rt==null)return rt;
     83     if(rt->ex&&a[rt->k1]==a[k1]&&a[rt->k2]==a[k2])return rt;
     84     if(a[rt->k1]<a[k1]||(a[rt->k1]==a[k1]&&a[rt->k2]<a[k2]))return find(rt->ch[1],k1,k2);
     85     else return find(rt->ch[0],k1,k2);
     86 }
     87 
     88 int w[N],maxn[N],maxpos[N];
     89 void pushup(int rt){
     90     if(a[maxn[rt<<1]]>=a[maxn[rt<<1|1]])
     91         maxn[rt]=maxn[rt<<1],
     92         maxpos[rt]=maxpos[rt<<1];
     93     else maxn[rt]=maxn[rt<<1|1],
     94         maxpos[rt]=maxpos[rt<<1|1];
     95 }
     96 void build(int rt,int l,int r){
     97     if(l==r){maxn[rt]=w[l];maxpos[rt]=l;return ;}
     98     int mid=(l+r)>>1;build(rt<<1,l,mid);build(rt<<1|1,mid+1,r);
     99     pushup(rt);
    100 }
    101 void update(int rt,int l,int r,int x,int y){
    102     if(l==r){maxn[rt]=y;maxpos[rt]=l;return ;}
    103     int mid=(l+r)>>1;
    104     if(x<=mid)update(rt<<1,l,mid,x,y);
    105     else update(rt<<1|1,mid+1,r,x,y);
    106     pushup(rt);
    107 }
    108 int MX,POS;
    109 void query(int rt,int l,int r,int x,int y){
    110     if(x<=l&&r<=y){
    111         if(a[MX]<a[maxn[rt]])
    112             MX=maxn[rt],POS=maxpos[rt];
    113         return;
    114     }
    115     int mid=(l+r)>>1;
    116     if(x<=mid)query(rt<<1,l,mid,x,y);
    117     if(y>mid)query(rt<<1|1,mid+1,r,x,y);
    118 }
    119 
    120 int n,m;
    121 int main(){
    122     init();
    123     scanf("%d%d",&n,&m);
    124     for(int i=1;i<=n;i++)w[i]=1;
    125     build(1,1,n);
    126     char ch[2];
    127     int x,y,z,l,r;
    128     while(m--){
    129         scanf("%s",ch);
    130         if(ch[0]=='C'){
    131             scanf("%d%d%d",&x,&y,&z);
    132             Node *now=find(root,w[x],w[y]);
    133             if(now!=null)w[z]=now->id;
    134             else{insert(w[x],w[y]);w[z]=tot;}
    135             update(1,1,n,z,w[z]);
    136         }
    137         if(ch[0]=='Q'){
    138             scanf("%d%d",&l,&r);
    139             MX=POS=0;query(1,1,n,l,r);
    140             printf("%d
    ",POS);
    141         }
    142     }
    143     return 0;
    144 }
    View Code
  • 相关阅读:
    【APIO2008】免费道路[最小生成树 kruskal]
    【2019.8.13】
    【矩阵】
    [POI2008]BLO-Blockade [tarjan 割点]
    poj1458 最长公共子序列 (动态规划)
    最长上升子序列
    poj1163 数字三角形 (动态规划)
    快速幂 (分治)
    求排列的逆序数(分治)
    快速排序 (分治)
  • 原文地址:https://www.cnblogs.com/Ren-Ivan/p/8287680.html
Copyright © 2011-2022 走看看