码迷,mamicode.com
首页 > 其他好文 > 详细

1901: Zju2112 Dynamic Rankings

时间:2017-01-13 09:01:51      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:接下来   out   namespace   names   char   lowbit   uml   printf   memory   

1901: Zju2112 Dynamic Rankings

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 7339  Solved: 3055
[Submit][Status][Discuss]

Description

给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]……a[j]中第k小的数是多少(1≤k≤j-i+1),并且,你可以改变一些a[i]的值,改变后,程序还能针对改变后的a继续回答上面的问题。你需要编一个这样的程序,从输入文件中读入序列a,然后读入一系列的指令,包括询问指令和修改指令。对于每一个询问指令,你必须输出正确的回答。 第一行有两个正整数n(1≤n≤10000),m(1≤m≤10000)。分别表示序列的长度和指令的个数。第二行有n个数,表示a[1],a[2]……a[n],这些数都小于10^9。接下来的m行描述每条指令,每行的格式是下面两种格式中的一种。 Q i j k 或者 C i t Q i j k (i,j,k是数字,1≤i≤j≤n, 1≤k≤j-i+1)表示询问指令,询问a[i],a[i+1]……a[j]中第k小的数。C i t (1≤i≤n,0≤t≤10^9)表示把a[i]改变成为t。

Input

对于每一次询问,你都需要输出他的答案,每一个输出占单独的一行。

Output

 

Sample Input

5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3

Sample Output

3
6

HINT

 

20%的数据中,m,n≤100; 40%的数据中,m,n≤1000; 100%的数据中,m,n≤10000。

 

Source

 

 
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1e5+5;
const int M=2200001;
int n,m,cnt,top,a,b,X[N],A[N],B[N],v[N],num[N<<1],K[N],L[30],R[30];
int root[N],ls[M],rs[M],sum[M];
int lowbit(int x){
    return x&-x;
}
void insert(int &k,int last,int l,int r,int x,int add){
    k=++cnt;
    int mid=l+r>>1;
    ls[k]=ls[last];
    rs[k]=rs[last];
    sum[k]=sum[last]+add;
    if(l==r) return;
    if(x<=mid) insert(ls[k],ls[last],l,mid,x,add);
    else insert(rs[k],rs[last],mid+1,r,x,add);
}
     
int query(int l,int r,int k){
    if(l==r) return l;
    int mid=l+r>>1;
    int suml=0,sumr=0;
    for(int i=1;i<=a;i++)suml+=sum[ls[L[i]]];
    for(int i=1;i<=b;i++)sumr+=sum[ls[R[i]]];
    if(sumr-suml>=k){
        for(int i=1;i<=a;i++) L[i]=ls[L[i]];
        for(int i=1;i<=b;i++) R[i]=ls[R[i]];
        return query(l,mid,k);
    }
    else{
        for(int i=1;i<=a;i++) L[i]=rs[L[i]];
        for(int i=1;i<=b;i++) R[i]=rs[R[i]];
        return query(mid+1,r,k-(sumr-suml));
    }
}
     
int main(){
    scanf("%d%d",&n,&m);top=n;
    for(int i=1;i<=n;i++) scanf("%d",&v[i]),num[i]=v[i];
    char opt[6];
    for(int i=1;i<=m;i++){
        scanf("%s%d%d",opt,&A[i],&B[i]);
        if(opt[0]==Q) scanf("%d",&X[i]),K[i]=1;
        else num[++top]=B[i];
    }
    sort(num+1,num+top+1);
    int tot=unique(num+1,num+top+1)-num-1;
    for(int i=1;i<=n;i++){
        int t=lower_bound(num+1,num+tot+1,v[i])-num;
        for(int j=i;j<=n;j+=lowbit(j))
            insert(root[j],root[j],1,tot,t,1);
    }
    for(int i=1;i<=m;i++){
        if(K[i]){
            a=0,b=0;A[i]--;
            for(int j=A[i];j>=1;j-=lowbit(j)) L[++a]=root[j];
            for(int j=B[i];j>=1;j-=lowbit(j)) R[++b]=root[j];
            printf("%d\n",num[query(1,tot,X[i])]);
        }
        else{
            int t=lower_bound(num+1,num+tot+1,v[A[i]])-num;
            for(int j=A[i];j<=n;j+=lowbit(j)) 
            insert(root[j],root[j],1,tot,t,-1);
            v[A[i]]=B[i];
            t=lower_bound(num+1,num+tot+1,v[A[i]])-num;
            for(int j=A[i];j<=n;j+=lowbit(j)) 
            insert(root[j],root[j],1,tot,t,1);
        }
    }
}

 

1901: Zju2112 Dynamic Rankings

标签:接下来   out   namespace   names   char   lowbit   uml   printf   memory   

原文地址:http://www.cnblogs.com/shenben/p/6281390.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!