zoukankan      html  css  js  c++  java
  • luogu3380/bzoj3196 二逼平衡树 (树状数组套权值线段树)

    带修改区间K大值

    这题有很多做法,我的做法是树状数组套权值线段树,修改查询的时候都是按着树状数组的规则找出那log(n)个线段树根,然后一起往下做

    时空都是$O(nlog^2n)$的(如果离散化了的话),空间可能会被卡,但实际上点数不用开到特别大,N*200也能过

      1 #include<bits/stdc++.h>
      2 #define pa pair<int,int>
      3 #define CLR(a,x) memset(a,x,sizeof(a))
      4 using namespace std;
      5 typedef long long ll;
      6 const int maxn=5e4+10,maxp=maxn*200,inf=1e8;
      7 
      8 inline ll rd(){
      9     ll x=0;char c=getchar();int neg=1;
     10     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
     11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
     12     return x*neg;
     13 }
     14 
     15 int root[maxn],ch[maxp][2],v[maxp],pct;
     16 int num[maxn],tmp1[maxn],tmp2[maxn],N,M;
     17 
     18 inline int lowbit(int x){return x&(-x);}
     19 
     20 inline void update(int p){v[p]=v[ch[p][0]]+v[ch[p][1]];}
     21 inline void add(int &p,int l,int r,int x,int y){
     22     if(!p) p=++pct;
     23     if(l==r) v[p]+=y;
     24     else{
     25         int m=l+r>>1;
     26         if(x<=m) add(ch[p][0],l,m,x,y);
     27         else add(ch[p][1],m+1,r,x,y);
     28         update(p);
     29     }
     30 }
     31 inline void change(int x,int y){
     32     int ori=num[x];
     33     for(;x<=N;x+=lowbit(x)){
     34         if(ori!=-1) add(root[x],0,inf,ori,-1);
     35         add(root[x],0,inf,y,1);
     36     }
     37 }
     38 
     39 inline void reset(int x,int y){
     40     for(;y;y-=lowbit(y)) tmp1[y]=root[y];
     41     for(;x;x-=lowbit(x)) tmp2[x]=root[x];
     42 }
     43 inline bool pushdown(int x,int y,bool b){
     44     bool re=0;
     45     for(;y;y-=lowbit(y)) tmp1[y]=ch[tmp1[y]][b],re|=tmp1[y];
     46     for(;x;x-=lowbit(x)) tmp2[x]=ch[tmp2[x]][b],re|=tmp2[x];
     47     return re;
     48 }
     49 
     50 int query1(int l,int r,int x,int y,int k){
     51     if(k<0) return 1;
     52     if(l==r) return 1;
     53     int m=l+r>>1;
     54     if(k<=m){
     55         if(!pushdown(x,y,0)) return 1;
     56         return query1(l,m,x,y,k);
     57     }else{
     58         int w=0;
     59         for(int i=y;i;i-=lowbit(i)) w+=v[ch[tmp1[i]][0]];
     60         for(int i=x;i;i-=lowbit(i)) w-=v[ch[tmp2[i]][0]];
     61         if(!pushdown(x,y,1)) return w+1;
     62         return w+query1(m+1,r,x,y,k);
     63     }
     64 }
     65 int query2(int l,int r,int x,int y,int k){
     66     if(k<=0) return -1;
     67     int w=0;
     68     for(int i=y;i;i-=lowbit(i)) w+=v[tmp1[i]];
     69     for(int i=x;i;i-=lowbit(i)) w-=v[tmp2[i]];
     70     if(w<k) return -1;
     71     if(l==r) return l;
     72     int m=l+r>>1;w=0;
     73     for(int i=y;i;i-=lowbit(i)) w+=v[ch[tmp1[i]][0]];
     74     for(int i=x;i;i-=lowbit(i)) w-=v[ch[tmp2[i]][0]];
     75     if(k<=w){
     76         pushdown(x,y,0);
     77         return query2(l,m,x,y,k);
     78     }else{
     79         pushdown(x,y,1);
     80         return query2(m+1,r,x,y,k-w);
     81     }
     82 }
     83 
     84 int main(){
     85     //freopen(".in","r",stdin);
     86     int i,j,k;
     87     N=rd(),M=rd();
     88     CLR(num,-1);
     89     for(i=1;i<=N;i++){
     90         int x=rd();
     91         change(i,x);num[i]=x;
     92     }
     93     for(i=1;i<=M;i++){
     94         int a=rd(),b=rd(),c=rd();
     95         if(a==3){
     96             change(b,c);num[b]=c;
     97         }else{
     98             int d=rd();
     99             if(a==1){
    100                 reset(b-1,c);
    101                 printf("%d
    ",query1(0,inf,b-1,c,d));
    102             }else if(a==2){
    103                 reset(b-1,c);
    104                 printf("%d
    ",query2(0,inf,b-1,c,d));
    105             }else if(a==4){
    106                 reset(b-1,c);
    107                 int rk=query1(0,inf,b-1,c,d);
    108                 reset(b-1,c);
    109                 if(rk==1) printf("-2147483647
    ");
    110                 else printf("%d
    ",query2(0,inf,b-1,c,rk-1));
    111             }else if(a==5){
    112                 reset(b-1,c);
    113                 int rk=query1(0,inf,b-1,c,d+1);
    114                 reset(b-1,c);
    115                 int re=query2(0,inf,b-1,c,rk);
    116                 if(re==-1) printf("2147483647
    ");
    117                 else printf("%d
    ",re);
    118             }
    119         }
    120     }
    121     return 0;
    122 }
  • 相关阅读:
    封装一个通用递归算法,使用TreeIterator和TreeMap来简化你的开发工作。
    优化特性(Attribute)性能
    不需要了解任何底层知识,就可以汉化!Let`s go!!!
    颠覆你对方法调用的看法!
    实际项目中面向对象的最佳实践
    递归使用触发器
    关于稀疏数组
    121-django中的Http404处理
    120-在前端使用django-ckeditor,很简单,很方便
    119-用django实现评论功能
  • 原文地址:https://www.cnblogs.com/Ressed/p/9794799.html
Copyright © 2011-2022 走看看