分享

bzoj 1901 or hdu 5412

 印度阿三17 2019-08-18

1901: Zju2112 Dynamic Rankings

Time Limit:?10 Sec??Memory Limit:?128 MB
Submit:?9543??Solved:?4004
[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
? 带元素修改的区间第k大问题。? ? 这题的方法也有很多。?? 1.分块 2.整体二分 3.线段树套线段树 4.区间线段树套平衡树 5.权值线段树套平衡树? 6.替罪羊树套线段树 ? 附整体二分代码:?? 整体二分就是把修改操作看成是一个删除操作和一个添加操作,把这些操作和询问放在一起进行二分。?
  1 #include<bits/stdc  .h>
  2 using namespace std; 
  3 int const N=300000 10;  
  4 int const inf=1e9; 
  5 struct node{
  6     int x,num;  
  7     bool operator < (const node &rhs) const{
  8         return x<rhs.x;  
  9     }
 10 }a[N];  
 11 struct query{
 12     int x,num,opt,k,cnt,y,v;  
 13 }q[N],ta[N],tb[N];  
 14 int n,m,ans[N],c[N],sum,xa[N];  
 15 void update(int x,int v){
 16     for(int i=x;i<=n;i =(i&-i))  
 17         c[i] =v;  
 18 }
 19 int inline getsum(int x){
 20     int s=0;  
 21     for(int i=x;i;i-=(i&-i))  
 22         s =c[i];  
 23     return s;  
 24 }
 25 void calc(int l,int r,int ll,int mid){
 26     int left=1,right=n;   
 27     while (left<right){
 28         int Mid=(left right)/2;  
 29         if(a[Mid].x>=ll) right=Mid; 
 30         else left=Mid 1;  
 31     }
 32     for(int i=left;i<=n && a[i].x<=mid;i  )  
 33     {
 34         if(a[i].x>=ll) update(a[i].num,1); 
 35     }
 36     for(int i=l;i<=r;i  ){
 37         if(q[i].opt==1 && q[i].v<=mid) update(q[i].num,1); 
 38         if(q[i].opt==2 && q[i].v<=mid) update(q[i].num,-1);  
 39         if(q[i].opt==3) q[i].cnt=getsum(q[i].y)-getsum(q[i].x-1);  
 40     }
 41     for(int i=left;i<=n && a[i].x<=mid;i  )  
 42         if(a[i].x>=ll) update(a[i].num,-1);  
 43     for(int i=l;i<=r;i  ){
 44         if(q[i].opt==1 && q[i].v<=mid) update(q[i].num,-1);  
 45         if(q[i].opt==2 && q[i].v<=mid) update(q[i].num,1); 
 46     }
 47 }
 48 void dfs(int l,int r,int ll,int rr){
 49     if(l>r) return; 
 50     if(ll==rr){
 51         for(int i=l;i<=r;i  ) 
 52             if(q[i].k) ans[q[i].num]=ll; 
 53         return;  
 54     }
 55     int mid=(ll rr)/2;  
 56     calc(l,r,ll,mid);  
 57     int s1=0,s2=0;   
 58     for(int i=l;i<=r;i  ){
 59         if(q[i].k){
 60             if(q[i].cnt>=q[i].k) ta[  s1]=q[i]; 
 61             else  q[i].k-=q[i].cnt,tb[  s2]=q[i];  
 62         }else {
 63             if(q[i].v<=mid) ta[  s1]=q[i];  
 64             else  tb[  s2]=q[i];  
 65         }
 66     }
 67     int p=l;  
 68     for(int i=1;i<=s1;i  )  q[p  ]=ta[i];  
 69     for(int i=1;i<=s2;i  )  q[p  ]=tb[i];  
 70     dfs(l,l s1-1,ll,mid);  
 71     dfs(l s1,r,mid 1,rr);  
 72 }
 73 int main(){
 74     while (scanf("%d",&n)!=EOF)
 75     {
 76         for(int i=1;i<=n;i  ){
 77             scanf("%d",&a[i].x);  
 78             a[i].num=i; 
 79             xa[i]=a[i].x;  
 80         }  
 81         sum=0;  
 82         scanf("%d",&m);  
 83         memset(q,0,sizeof(q));
 84         memset(c,0,sizeof(c));  
 85         for(int i=1;i<=m;i  ){
 86             int t;  
 87             scanf("%d",&t);  
 88             if(t==1) {
 89                   sum; 
 90                 q[sum].opt=1;  
 91                 scanf("%d%d",&q[sum].num,&q[sum].v);  
 92                   sum;  
 93                 q[sum].opt=2;   
 94                 q[sum].num=q[sum-1].num; 
 95                 q[sum].v=xa[q[sum-1].num];  
 96                 xa[q[sum].num]=q[sum-1].v;  
 97             }else {
 98                   sum; 
 99                 q[sum].opt=3;  
100                 scanf("%d%d%d",&q[sum].x,&q[sum].y,&q[sum].k);  
101                 q[sum].num=i;   
102             }
103         }
104         sort(a 1,a n 1);
105         memset(ans,0,sizeof(ans));  
106         dfs(1,sum,1,inf);  
107         for(int i=1;i<=m;i  )  
108             if(ans[i]) printf("%d\n",ans[i]); 
109     }
110     return 0;
111 }
View Code

?

来源:https://www./content-4-396951.html

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约