hdu5412

链接:hdu5412

题解

  • 注意这题是单点修改,整体二分一下就可以AC,一发过。。。
  • 把所有修改操作看成把这个点删了,再加上一个数。
  • 每次二分一个mid,对于要修改的数小于(因为求得是第k大)这个值,直接加上然后放到左区间,否则放到右区间,对于查询操作,如果这个区间内大于mid的数x小于k那么显然答案应该比mid大,k-=x后放到右区间,否则放到左区间,注意这里的顺序是不能改变的QAQ
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #define rep(i,x,y) for(int i=x;i<=y;++i)
    #define repd(i,x,y) for(int i=x;i>=y;--i)
    #define lowbit(x) x&(-x)
    #define ll long long
    using namespace std;
    const int N=1e6+7;
    const int inf=0x3f3f3f3f;
    int n,m,ans[N],tr[N],a[N];
    struct node{
    int x,y,k,cnt,num;
    inline void init(int _x,int _y,int _k,int _cnt,int _num){x=_x;y=_y;k=_k;cnt=_cnt;num=_num;}
    }q[N],b[N];
    inline void update(int x,int y){for(int i=x;i<=n;i+=lowbit(i))tr[i]+=y;}
    inline int query(int x){ll res=0;for(int i=x;i;i-=lowbit(i))res+=tr[i];return res;}
    void solve(int L,int R,int LL,int RR){
    if(LL==RR){rep(i,L,R)if(q[i].k)ans[q[i].num]=LL;return ;}
    int mid=LL+RR>>1,l=L,r=R;
    rep(i,L,R){
    if(q[i].k){
    q[i].cnt=query(q[i].y)-query(q[i].x-1);
    if(q[i].cnt<q[i].k)q[i].k-=q[i].cnt,b[r--]=q[i];
    else b[l++]=q[i];
    }
    else {
    if(q[i].y<=mid)b[l++]=q[i],update(q[i].x,q[i].cnt);
    else b[r--]=q[i];
    }
    }
    rep(i,L,R)if(!q[i].k&&q[i].y<=mid)update(q[i].x,-q[i].cnt);
    rep(i,L,l-1)q[i]=b[i];
    for(int i=l,j=R;i<=R;--j,++i)q[i]=b[j];
    if(l!=L)solve(L,l-1,LL,mid);
    if(r!=R)solve(r+1,R,mid+1,RR);
    }
    int main(){
    while(~scanf("%d",&n)){
    int len=0;
    rep(i,1,n){scanf("%d",&a[i]);q[++len].init(i,a[i],0,1,0);}
    scanf("%d",&m);
    rep(i,1,m){
    int op;scanf("%d",&op);
    if(op&1){
    int x,y;
    scanf("%d%d",&x,&y);
    q[++len].init(x,a[x],0,-1,0);
    q[++len].init(x,y,0,1,0);
    a[x]=y;
    ans[i]=0;
    }
    else {
    int x,y,z;
    scanf("%d%d%d",&x,&y,&z);
    q[++len].init(x,y,z,0,i);
    }
    }
    solve(1,len,1,inf);
    rep(i,1,m)if(ans[i])printf("%d\n",ans[i]);
    }
    return 0;
    }