zoukankan      html  css  js  c++  java
  • bzoj1901 Zju2112 Dynamic Rankings*

    bzoj1901 Zju2112 Dynamic Rankings

    题意:

    维护数据结构,支持区间第k大和单点修改。序列大小,操作数≤10000

    题解:

    构造一个树状数组,树状数组中的节点用主席树维护。一开始先插入序列中的节点,然后对于修改,就是将经过的树状数组上的主席树删除旧值,再插入新值;对于查询,还是和普通主席树一样二分,但此时的前缀和是由树状数组中数棵主席树查询节点的和得到的。反思:空间复杂度粗略计算是O(nlog^2n),常数大概是乘个7,8,在bzoj上内存达到了80M,幸好bzoj上空间给的是128M,听说原题空间是31M,规模是30000,我要是做原题早挂了!不知道怎么办QAQ

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define inc(i,j,k) for(int i=j;i<=k;i++)
     5 #define maxn 10010
     6 #define lb(x) x&-x
     7 using namespace std;
     8 
     9 inline int read(){
    10     char ch=getchar(); int f=1,x=0;
    11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    12     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    13     return f*x;
    14 }
    15 int n,m,a[maxn],v[maxn*2],tot,root[maxn],sz[3*maxn*15*15],ch[3*maxn*15*15][2],cnt;
    16 struct ask{char opt[3]; int l,r,k;}; ask asks[maxn];
    17 struct ls{int id,v;}; ls lss[maxn*2]; int lsss;
    18 bool cmp(ls a,ls b){return a.v<b.v;}
    19 void lisan(){
    20     inc(i,1,n)lss[++lsss]=(ls){i,a[i]};
    21     inc(i,1,m)if(asks[i].opt[0]=='C')lss[++lsss]=(ls){n+i,asks[i].k};
    22     sort(lss+1,lss+1+lsss,cmp);
    23     inc(i,1,lsss){
    24         if(i==1||lss[i].v!=lss[i-1].v)tot++,v[tot]=lss[i].v;
    25         if(lss[i].id<=n)a[lss[i].id]=tot;else asks[lss[i].id-n].k=tot;
    26     }
    27 }
    28 int build(int l,int r){
    29     int x=++cnt; sz[x]=0; if(l==r)return x;
    30     int mid=(l+r)>>1; ch[x][0]=build(l,mid); ch[x][1]=build(mid+1,r); return x;
    31 }
    32 void updseg(int &x,int y,int l,int r,int a){
    33     cnt++; ch[cnt][0]=ch[x][0]; ch[cnt][1]=ch[x][1]; sz[cnt]=sz[x]+a; x=cnt; if(l==r)return;
    34     int mid=(l+r)>>1; if(y<=mid)updseg(ch[x][0],y,l,mid,a); if(y>mid)updseg(ch[x][1],y,mid+1,r,a);
    35 }
    36 int queryseg(int x,int ql,int qr,int l,int r){
    37     if(ql<=l&&r<=qr)return sz[x]; int mid=(l+r)>>1,q=0;
    38     if(ql<=mid)q+=queryseg(ch[x][0],ql,qr,l,mid); if(mid<qr)q+=queryseg(ch[x][1],ql,qr,mid+1,r);
    39     return q;
    40 }
    41 void updbit(int x,int y,int a){
    42     while(x<=n)updseg(root[x],y,1,tot,a),x+=lb(x);
    43 }
    44 int querybit(int x,int ql,int qr){
    45     int q=0; while(x>=1)q+=queryseg(root[x],ql,qr,1,tot),x-=lb(x); return q;
    46 }
    47 void init(){
    48     int x=build(1,tot); inc(i,1,n)root[i]=x; inc(i,1,n)updbit(i,a[i],1);
    49 }
    50 int query(int ql,int qr,int k){
    51     int l=1,r=tot;
    52     while(1){
    53         int mid=(l+r)>>1; int x=querybit(qr,l,mid)-querybit(ql-1,l,mid);
    54         if(x>=k)r=mid;else l=mid+1,k-=x; if(l==r)return l;
    55     }
    56 }
    57 void modify(int x,int y){
    58     updbit(x,a[x],-1); updbit(x,y,1); a[x]=y;
    59 }
    60 int main(){
    61     n=read(); m=read(); inc(i,1,n)a[i]=read();
    62     inc(i,1,m){
    63         scanf("%s",asks[i].opt);
    64         if(asks[i].opt[0]=='Q')asks[i].l=read(),asks[i].r=read(),asks[i].k=read();
    65         if(asks[i].opt[0]=='C')asks[i].l=read(),asks[i].k=read();
    66     }
    67     lisan(); init();
    68     inc(i,1,m){
    69         if(asks[i].opt[0]=='Q')printf("%d
    ",v[query(asks[i].l,asks[i].r,asks[i].k)]);
    70         if(asks[i].opt[0]=='C')modify(asks[i].l,asks[i].k);
    71     }
    72     return 0;
    73 }

    20160813

  • 相关阅读:
    java泛型
    java集合
    java面向对象
    java常用类
    二分查找
    递归
    选择排序+冒泡排序
    threejs入门简单例子
    css表格合并边框以及单元格宽度计算方式
    Spring Boot 有哪些优点?
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5777957.html
Copyright © 2011-2022 走看看