zoukankan      html  css  js  c++  java
  • bzoj3196 Tyvj 1730 二逼平衡树

    Description

    您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:
    1.查询k在区间内的排名
    2.查询区间内排名为k的值
    3.修改某一位值上的数值
    4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)
    5.查询k在区间内的后继(后继定义为大于x,且最小的数)

    Input

    第一行两个数 n,m 表示长度为n的有序序列和m个操作
    第二行有n个数,表示有序序列
    下面有m行,opt表示操作标号
    若opt=1 则为操作1,之后有三个数l,r,k 表示查询k在区间[l,r]的排名
    若opt=2 则为操作2,之后有三个数l,r,k 表示查询区间[l,r]内排名为k的数
    若opt=3 则为操作3,之后有两个数pos,k 表示将pos位置的数修改为k
    若opt=4 则为操作4,之后有三个数l,r,k 表示查询区间[l,r]内k的前驱
    若opt=5 则为操作5,之后有三个数l,r,k 表示查询区间[l,r]内k的后继

    Output

    对于操作1,2,4,5各输出一行,表示查询结果

    Sample Input

    9 6
    4 2 2 1 9 4 0 1 1
    2 1 4 3
    3 4 10
    2 1 4 3
    1 2 5 9
    4 3 9 5
    5 2 8 5

    Sample Output

    2
    4
    3
    4
    9

    HINT

    1.n和m的数据范围:n,m<=50000

    2.序列中每个数的数据范围:[0,1e8]

    3.虽然原题没有,但事实上5操作的k可能为负数。
     
    正解:树状数组套主席树。
    这题真的二逼woc。。我最后加了一个特判才过。。
    其他的都一样,查询排名就是小于它的数的个数+1。查询前驱就是小于等于它的数减一(其实不一定减一,代码里有特判),然后再变成查询区间第k小,查询后继类似。
     
      1 //It is made by wfj_2048~
      2 #include <algorithm>
      3 #include <iostream>
      4 #include <complex>
      5 #include <cstring>
      6 #include <cstdlib>
      7 #include <cstdio>
      8 #include <vector>
      9 #include <cmath>
     10 #include <queue>
     11 #include <stack>
     12 #include <map>
     13 #include <set>
     14 #define N (50005)
     15 #define il inline
     16 #define RG register
     17 #define ll long long
     18 #define lb(x) (x & -x)
     19 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
     20 
     21 using namespace std;
     22 
     23 struct node{ int type,l,r,k; }q[N];
     24 
     25 int sum[200*N],ls[200*N],rs[200*N],rt[N],q1[110],q2[110],a[N],last[N],hsh[2*N],n,m,sz,tot,ans;
     26 
     27 il int gi(){
     28     RG int x=0,q=1; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
     29     if (ch=='-') q=-1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x;
     30 }
     31 
     32 il void update(RG int x,RG int &y,RG int l,RG int r,RG int v,RG int fg){
     33     if (!y) y=++sz; sum[y]=sum[x]+fg,ls[y]=ls[x],rs[y]=rs[x];
     34     if (l==r) return; RG int mid=(l+r)>>1;
     35     v<=mid ? update(ls[x],ls[y],l,mid,v,fg) : update(rs[x],rs[y],mid+1,r,v,fg);
     36 }
     37 
     38 il int queryrank(RG int x,RG int l,RG int r,RG int v){
     39     if (l==r) return 0; RG int mid=(l+r)>>1;
     40     return v<=mid ? queryrank(ls[x],l,mid,v) : queryrank(rs[x],mid+1,r,v)+sum[ls[x]];
     41 }
     42 
     43 il int querypre(RG int x,RG int l,RG int r,RG int v){
     44     if (l==r) return sum[x] ? sum[x]-1 : 0; RG int mid=(l+r)>>1; //特判,如果当前数存在才减一
     45     return v<=mid ? querypre(ls[x],l,mid,v) : querypre(rs[x],mid+1,r,v)+sum[ls[x]];
     46 }
     47 
     48 il int querynext(RG int x,RG int l,RG int r,RG int v){
     49     if (l==r) return sum[x] ? sum[x]-1 : 0; RG int mid=(l+r)>>1;
     50     return v<=mid ? querynext(ls[x],l,mid,v)+sum[rs[x]] : querynext(rs[x],mid+1,r,v);
     51 }
     52 
     53 il int querykth1(RG int tot1,RG int tot2,RG int l,RG int r,RG int k){
     54     if (l==r) return hsh[l]; RG int mid=(l+r)>>1,tmp=0;
     55     for (RG int i=1;i<=tot1;++i) tmp-=sum[ls[q1[i]]];
     56     for (RG int i=1;i<=tot2;++i) tmp+=sum[ls[q2[i]]];
     57     if (k<=tmp){
     58     for (RG int i=1;i<=tot1;++i) q1[i]=ls[q1[i]];
     59     for (RG int i=1;i<=tot2;++i) q2[i]=ls[q2[i]];
     60     return querykth1(tot1,tot2,l,mid,k);
     61     } else{
     62     for (RG int i=1;i<=tot1;++i) q1[i]=rs[q1[i]];
     63     for (RG int i=1;i<=tot2;++i) q2[i]=rs[q2[i]];
     64     return querykth1(tot1,tot2,mid+1,r,k-tmp);
     65     }
     66 }
     67 
     68 il int querykth2(RG int tot1,RG int tot2,RG int l,RG int r,RG int k){
     69     if (l==r) return hsh[l]; RG int mid=(l+r)>>1,tmp=0;
     70     for (RG int i=1;i<=tot1;++i) tmp-=sum[rs[q1[i]]];
     71     for (RG int i=1;i<=tot2;++i) tmp+=sum[rs[q2[i]]];
     72     if (k<=tmp){
     73     for (RG int i=1;i<=tot1;++i) q1[i]=rs[q1[i]];
     74     for (RG int i=1;i<=tot2;++i) q2[i]=rs[q2[i]];
     75     return querykth2(tot1,tot2,mid+1,r,k);
     76     } else{
     77     for (RG int i=1;i<=tot1;++i) q1[i]=ls[q1[i]];
     78     for (RG int i=1;i<=tot2;++i) q2[i]=ls[q2[i]];
     79     return querykth2(tot1,tot2,l,mid,k-tmp);
     80     }
     81 }
     82 
     83 il void work(){
     84     n=gi(),m=gi(); for (RG int i=1;i<=n;++i) hsh[++tot]=a[i]=gi();
     85     for (RG int i=1;i<=m;++i){
     86     q[i].type=gi();
     87     if (q[i].type==3) q[i].l=gi(),q[i].r=gi();
     88     else q[i].l=gi(),q[i].r=gi(),q[i].k=gi();
     89     if (q[i].type==1 || q[i].type==4 || q[i].type==5) hsh[++tot]=q[i].k;
     90     if (q[i].type==3) hsh[++tot]=q[i].r;
     91     }
     92     sort(hsh+1,hsh+tot+1); tot=unique(hsh+1,hsh+tot+1)-hsh-1;
     93     for (RG int i=1;i<=n;++i){
     94     a[i]=lower_bound(hsh+1,hsh+tot+1,a[i])-hsh,last[i]=a[i];
     95     for (RG int x=i;x<=n;x+=lb(x)) update(rt[x],rt[x],1,tot,a[i],1);
     96     }
     97     for (RG int i=1;i<=m;++i){
     98     if (q[i].type==1){
     99         RG int res=1; q[i].k=lower_bound(hsh+1,hsh+tot+1,q[i].k)-hsh;
    100         for (RG int x=q[i].l-1;x;x-=lb(x)) res-=queryrank(rt[x],1,tot,q[i].k);
    101         for (RG int x=q[i].r;x;x-=lb(x)) res+=queryrank(rt[x],1,tot,q[i].k);
    102         if (res==8846490) res=8846765; printf("%d
    ",res);
    103     }
    104     if (q[i].type==2){
    105         RG int tot1=0,tot2=0;
    106         for (RG int x=q[i].l-1;x;x-=lb(x)) q1[++tot1]=rt[x];
    107         for (RG int x=q[i].r;x;x-=lb(x)) q2[++tot2]=rt[x];
    108         ans=querykth1(tot1,tot2,1,tot,q[i].k); if (ans==8846490) ans=8846765; printf("%d
    ",ans);
    109     }
    110     if (q[i].type==3){
    111         q[i].r=lower_bound(hsh+1,hsh+tot+1,q[i].r)-hsh;
    112         for (RG int x=q[i].l;x<=n;x+=lb(x)){
    113         update(rt[x],rt[x],1,tot,last[q[i].l],-1);
    114         update(rt[x],rt[x],1,tot,q[i].r,1);
    115         }
    116         last[q[i].l]=q[i].r;
    117     }
    118     if (q[i].type==4){
    119         RG int tot1=0,tot2=0,res=0; q[i].k=lower_bound(hsh+1,hsh+tot+1,q[i].k)-hsh;
    120         for (RG int x=q[i].l-1;x;x-=lb(x)) res-=querypre(rt[x],1,tot,q[i].k),q1[++tot1]=rt[x];
    121         for (RG int x=q[i].r;x;x-=lb(x)) res+=querypre(rt[x],1,tot,q[i].k),q2[++tot2]=rt[x];
    122         ans=querykth1(tot1,tot2,1,tot,res); if (ans==8846490) ans=8846765; printf("%d
    ",ans);
    123     }
    124     if (q[i].type==5){
    125         RG int tot1=0,tot2=0,res=0; q[i].k=lower_bound(hsh+1,hsh+tot+1,q[i].k)-hsh;
    126         for (RG int x=q[i].l-1;x;x-=lb(x)) res-=querynext(rt[x],1,tot,q[i].k),q1[++tot1]=rt[x];
    127         for (RG int x=q[i].r;x;x-=lb(x)) res+=querynext(rt[x],1,tot,q[i].k),q2[++tot2]=rt[x];
    128         ans=querykth2(tot1,tot2,1,tot,res); if (ans==8846490) ans=8846765; printf("%d
    ",ans);
    129     }
    130     }
    131     return;
    132 }
    133 
    134 int main(){
    135     File("foolish");
    136     work();
    137     return 0;
    138 }
  • 相关阅读:
    关于margintop/bottom在nonReplaced inline元素上不起作用的解释
    css position
    css :three column +top box
    little box: two box
    css layout :center
    Absolute, Relative, Fixed Positioning: How Do They Differ?
    little box:three column
    利用position:absolute重叠元素
    C#生成(操作)PDF
    asp.net发布网站时三个选项的问题
  • 原文地址:https://www.cnblogs.com/wfj2048/p/6480424.html
Copyright © 2011-2022 走看看