• P2617 Dynamic Rankings


    题目描述

    给定一个含有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。

    输出格式:

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

    输入输出样例

    输入样例#1: 
    5 3
    3 2 1 4 7
    Q 1 4 3
    C 2 6
    Q 2 5 3
    输出样例#1: 
    3
    6
    

    说明

    10%的数据中,m,n≤100;

    20%的数据中,m,n≤1000;

    50%的数据中,m,n≤10000。

    对于所有数据,m,n≤100000

    请注意常数优化,但写法正常的整体二分和树套树都可以以大约1000ms每个点的时间过。

    来源:bzoj1901

    本题数据为洛谷自造数据,使用CYaRon耗时5分钟完成数据制作。

    Solution:

      本题带修改主席树板子题

      原题数据用分快或者线段树套平衡树可过,加强版的话貌似只能整体二分或者带修改主席树了。

      说下带修改主席树,其实很简单。

      主席树可以理解为前缀式线段树,而对于前缀和上的修改,维护利器就是树状数组啦。  

      我们在普通主席树建树的基础上,对i节点的建树,改为对Bit上包含该节点的每个位置都构建主席树。

      那么单点修改时直接先去掉该节点,改完值后再插入树中 ; 而区间查询第k大的值,直接取出Bit维护的$r,l-1$的各个前缀主席树相减,得到该段区间上的分布情况,然后普通主席树的第k大值查询就好了。

    代码:

    /*Code by 520 -- 9.19*/
    #include<bits/stdc++.h>
    #define il inline
    #define ll long long
    #define RE register
    #define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
    #define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
    #define lowbit(x) (x&-x)
    using namespace std;
    const int N=100005;
    int n,m,rt[N],cnt,tot,*Q[N<<1],val[N];
    int a[N],qa[N],qb[N],qc[N],qd[N],X[N],Y[N],tx,ty;
    struct node{
        int ls,rs,siz;
    }t[N*600];
    char s[10];
    
    int gi(){
        int a=0;char x=getchar();bool f=0;
        while((x<'0'||x>'9')&&x!='-') x=getchar();
        if(x=='-') x=getchar(),f=1;
        while(x>='0'&&x<='9') a=(a<<3)+(a<<1)+(x^48),x=getchar();
        return f?-a:a;
    }
    
    il bool cmp(const int *a,const int *b){return *a<*b;}
    
    void ins(int l,int r,int k,int x,int lst,int &rt){
        if(!rt) rt=++tot; t[rt]=t[lst],t[rt].siz+=x;
        if(l==r) return;
        int m=l+r>>1;
        if(k<=m) ins(l,m,k,x,t[lst].ls,t[rt].ls);
        else ins(m+1,r,k,x,t[lst].rs,t[rt].rs);
    }
    
    il void update(int i,int v){
        int k=a[i];
        while(i<=n) ins(1,cnt,k,v,rt[i],rt[i]),i+=lowbit(i);
    }
    
    int query(int x){
        int l=1,r=cnt,k=qc[x];
        tx=ty=0;
        for(RE int i=qa[x]-1;i;i-=lowbit(i)) X[++tx]=rt[i];
        for(RE int i=qb[x];i;i-=lowbit(i)) Y[++ty]=rt[i];
        while(l<r){
            int m=l+r>>1,res=0;
            For(i,1,tx) res-=t[t[X[i]].ls].siz;
            For(i,1,ty) res+=t[t[Y[i]].ls].siz;
            if(k<=res) {
                For(i,1,tx) X[i]=t[X[i]].ls;
                For(i,1,ty) Y[i]=t[Y[i]].ls;
                r=m;
            }
            else {
                For(i,1,tx) X[i]=t[X[i]].rs;
                For(i,1,ty) Y[i]=t[Y[i]].rs;
                l=m+1,k-=res;
            }
        }
        return l;
    }
    
    int main(){
        n=gi(),m=gi();
        For(i,1,n) a[i]=gi(),Q[++tot]=&a[i];
        For(i,1,m) {
            scanf("%s",s),qa[i]=gi(),qb[i]=gi();
            if(s[0]=='Q') qc[i]=gi(); else Q[++tot]=&qb[i];
        }
        sort(Q+1,Q+tot+1,cmp);
        int lst=-1;
        For(i,1,tot) if(*Q[i]!=lst) lst=*Q[i],*Q[i]=++cnt,val[cnt]=lst; else *Q[i]=cnt;
        memset(&t[tot=0],0,sizeof(t[tot]));
        For(i,1,n) update(i,1);
        For(i,1,m) 
            if(qc[i]) printf("%d
    ",val[query(i)]);
            else update(qa[i],-1),a[qa[i]]=qb[i],update(qa[i],1);
        return 0;
    }
  • 相关阅读:
    poj 2391 Ombrophobic Bovines
    混合欧拉回路poj 1637 Sightseeing tour
    POJ1149-PIGS
    C
    B
    A
    C
    B
    A
    O
  • 原文地址:https://www.cnblogs.com/five20/p/9678890.html
Copyright © 2020-2023  润新知