zoj2112

这道题是要求待修改的区间第k值,看的kuangbin的树状数组加主席树,这种方法是离线的。本来是想做hdu5412的,结果超时,所以只能交了zoj2110。没什么多说的,就是模板题。如果要求第k大,只要做相应的修改就行了,有多种修改的方法,只要能的出正确答案就行。

参考代码:http://www.cnblogs.com/kuangbin/p/3308118.html

(今天为了看书,没有吃包子,只吃了面包,本来想着反正有番茄酱,但是看到队友吃包子,还是各种口水流羡慕

2015.8.31:

回忆了一下模板。但是写时还是要注意细节。不过只要理解了原理,什么时候都能写,就是时间长短的问题。今天中午买了一个包子,结果划卡划多了,结果又多给了一个,吃的那叫一个痛哭流涕(因为菜太辣了!吐舌头)。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 50010
#define M 10010
#define Q 2600000

struct querynode{
    int type;
    int l;
    int r;
    int k;
};
int c[Q],lson[Q],rson[Q];
int T[N],S[N],use[N];
int newid[2*N];
int num[N];
bool usemark[N];
querynode queryarray[M];
int n,m;
int tot;

void lisanhua(){
    sort(newid+1,newid+m+1);
    m=unique(newid+1,newid+m+1)-(newid+1);
}

int build(int l,int r){
    int root=tot++;

    c[root]=0;
    if(l<r){
        int middle=(l+r)>>1;

        lson[root]=build(l,middle);
        rson[root]=build(middle+1,r);
    }
    else{
        lson[root]=-1;
        rson[root]=-1;
    }

    return root;
}

int insert(int froroot,int anum,int cou){
    int root=tot++,temproot=root;
    int l=1,r=m;
    c[root]=c[froroot]+cou;

    while(l<r){
        int middle=(l+r)>>1;

        if(anum<=middle){
            r=middle;
            lson[temproot]=tot++;
            rson[temproot]=rson[froroot];
            temproot=lson[temproot];
            froroot=lson[froroot];
        }
        else{
            l=middle+1;
            lson[temproot]=lson[froroot];
            rson[temproot]=tot++;
            temproot=rson[temproot];
            froroot=rson[froroot];
        }
        c[temproot]=c[froroot]+cou;
    }

    return root;
}

int numhash(int x){
    return lower_bound(newid+1,newid+m+1,x)-newid;
}

int lowbit(int x){
    return (~x+1)&x;
}

void modify(int x,int anum,int cou){
    while(x<=n){
        S[x]=insert(S[x],anum,cou);
        x=x+lowbit(x);
    }
}

int sum(int x){
    int ans=0;

    while(x>0){
        ans+=c[lson[use[x]]];
        x=x-lowbit(x);
    }

    return ans;
}

int query(int left,int right,int k){
    int l=1,r=m;
    int tempr=T[right],templ=T[left-1];

    for(int i=right;i>0;i=i-lowbit(i)){
        use[i]=S[i];
    }
    for(int i=left-1;i>0;i=i-lowbit(i)){
        use[i]=S[i];
    }

    while(l<r){
        int middle=(l+r)>>1;
        int cnt=sum(right)+c[lson[tempr]]-(sum(left-1)+c[lson[templ]]);

        if(cnt>=k){
            r=middle;
            memset(usemark,false,sizeof(usemark));
            for(int i=right;i>0;i=i-lowbit(i)){
                use[i]=lson[use[i]];
                usemark[i]=true;
            }
            for(int i=left-1;i>0;i=i-lowbit(i)){
                if(!usemark[i]){
                    use[i]=lson[use[i]];
                }
            }
            tempr=lson[tempr];
            templ=lson[templ];
        }
        else{
            l=middle+1;
            memset(usemark,false,sizeof(usemark));
            for(int i=right;i>0;i=i-lowbit(i)){
                use[i]=rson[use[i]];
                usemark[i]=true;
            }
            for(int i=left-1;i>0;i=i-lowbit(i)){
                if(!usemark[i]){
                    use[i]=rson[use[i]];
                }
            }
            tempr=rson[tempr];
            templ=rson[templ];
            k=k-cnt;
        }
    }

    return l;
}

int main(){
    int t;
    int q;
    char op[10];

    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&q);

        for(int i=1;i<=n;i++){
            scanf("%d",&num[i]);
            newid[i]=num[i];
        }
        m=n;
        for(int i=0;i<q;i++){
            scanf("%s",op);
            if(op[0]=='Q'){
                queryarray[i].type=0;
                scanf("%d%d%d",&queryarray[i].l,&queryarray[i].r,&queryarray[i].k);
            }
            else{
                queryarray[i].type=1;
                scanf("%d%d",&queryarray[i].l,&queryarray[i].r);
                newid[++m]=queryarray[i].r;
            }
        }

        tot=0;
        lisanhua();
        T[0]=build(1,m);
        for(int i=1;i<=n;i++){
            T[i]=insert(T[i-1],numhash(num[i]),1);
        }
        for(int i=1;i<=n;i++){
            S[i]=T[0];
        }

        for(int i=0;i<q;i++){
            /*for(int i=1;i<=n;i++){
                printf("%d ",num[i]);
            }
            printf("\n");*/

            if(queryarray[i].type==0){
                printf("%d\n",newid[query(queryarray[i].l,queryarray[i].r,queryarray[i].k)]);
            }
            else if(queryarray[i].type==1){
                modify(queryarray[i].l,numhash(num[queryarray[i].l]),-1);
                modify(queryarray[i].l,numhash(queryarray[i].r),1);
                num[queryarray[i].l]=queryarray[i].r;
            }
        }
    }

    return 0;
}




posted @ 2015-08-26 10:36  buzhidaohahaha  阅读(218)  评论(0编辑  收藏  举报