zoukankan      html  css  js  c++  java
  • BZOJ1901: Zju2112 Dynamic Rankings

    题解:很显然的树套树 主席树+树状数组 动态维护区间权值 然后类似于查询区间第K大 复杂度nlog^2n 空间也如此

    #include <bits/stdc++.h>
    const int MAXN=2e4+10;
    using namespace std;
    int read(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return f*x;
    }
    typedef struct node{
        int l,r,sum;
    }node;
    node d[MAXN*201];
    int rt[MAXN];
    int cnt;
    int get_id(int x){return x&(-x);}
    void update(int &x,int y,int l,int r,int t,int vul){
        x=++cnt;d[x]=d[y];d[x].sum+=vul;
        if(l==r)return ;
        int mid=(l+r)>>1;
        if(t<=mid)update(d[x].l,d[y].l,l,mid,t,vul);
        else update(d[x].r,d[y].r,mid+1,r,t,vul);
    }
    int ans,sum;
    vector<int>v1;
    vector<int>v2;
    void querty(int l,int r,int k){
        if(l==r){ans=l;return ;}
        sum=0;
        int mid=(l+r)>>1;
        for(int i=0;i<v1.size();i++)sum+=d[d[v1[i]].l].sum;
        for(int i=0;i<v2.size();i++)sum-=d[d[v2[i]].l].sum;
       // cout<<l<<" "<<r<<" "<<sum<<endl;
        if(k<=sum){
        for(int i=0;i<v1.size();i++)v1[i]=d[v1[i]].l;
        for(int i=0;i<v2.size();i++)v2[i]=d[v2[i]].l;
        querty(l,mid,k);
        }
        else{
        for(int i=0;i<v1.size();i++)v1[i]=d[v1[i]].r;
        for(int i=0;i<v2.size();i++)v2[i]=d[v2[i]].r;
        querty(mid+1,r,k-sum);
        }
    }
    vector<int>vec;
    int a[MAXN];
    typedef struct Q{
        int op,l,r,k;
    }Q;
    Q q[MAXN];
    int main(){
        int n,m;n=read();m=read();
        for(int i=1;i<=n;i++)a[i]=read(),vec.push_back(a[i]);
        char ch;
        for(int i=1;i<=m;i++){
        scanf(" %c",&ch);
        if(ch=='Q'){q[i].op=1;q[i].l=read();q[i].r=read();q[i].k=read();}
        else{q[i].op=2;q[i].l=read();q[i].r=read();vec.push_back(q[i].r);}
        }
        sort(vec.begin(),vec.end());
        int sz=unique(vec.begin(),vec.end())-vec.begin();
        for(int i=1;i<=n;i++){
        a[i]=lower_bound(vec.begin(),vec.begin()+sz,a[i])-vec.begin()+1;
    //  cout<<a[i]<<" ";
        for(int j=i;j<=n;j+=get_id(j))update(rt[j],rt[j],1,sz,a[i],1);
    //  cout<<endl;
        }
    //    cout<<endl;
        for(int i=1;i<=m;i++){
        if(q[i].op==2){
            q[i].r=lower_bound(vec.begin(),vec.begin()+sz,q[i].r)-vec.begin()+1;
            for(int j=q[i].l;j<=n;j+=get_id(j))update(rt[j],rt[j],1,sz,a[q[i].l],-1),update(rt[j],rt[j],1,sz,q[i].r,1);
            a[q[i].l]=q[i].r;
        }
        else{
            v1.clear();v2.clear();
    //      cout<<q[i].l<<" "<<q[i].r<<" "<<q[i].k<<endl;
            for(int j=q[i].r;j>0;j-=get_id(j))v1.push_back(rt[j]);
           // cout<<endl;
            for(int j=q[i].l-1;j>0;j-=get_id(j))v2.push_back(rt[j]);
           // cout<<endl;
            querty(1,sz,q[i].k);
            printf("%d
    ",vec[ans-1]);
        }
        }
        return 0;
    }
    

    1901: Zju2112 Dynamic Rankings

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 9085  Solved: 3802
    [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继续回答上面的问题。

    Input

    第一行有两个正整数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
    m,n≤10000

    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

    Source

  • 相关阅读:
    HDU 1124 Factorial
    hdu 1690 Bus System
    hdu 1113 Word Amalgamation
    POJ 2482 Stars in Your Window
    hdu 1385 ZOJ 1456 Minimum Transport Cost(经典floyd)
    hdu 1907 John
    VMware 虚拟机 安装 UBuntu 9.10 命令模式转换成窗口模试
    #pragma CODE_SEG __NEAR_SEG NON_BANKED详解
    Ubuntu 下Hadoop 伪分布式 hadoop0.20.2.tar.gz 的安装
    文件拷贝代码以及疑问
  • 原文地址:https://www.cnblogs.com/wang9897/p/9213026.html
Copyright © 2011-2022 走看看