程序改变世界,教育改变未来

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

带修改区间第k小,使用整体二分。

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #define lowbit(x) (x&-(x))
  6 using namespace std;
  7 #define MAXN 100005
  8 struct node
  9 {
 10     int tp,pos,val,ed,cur,addr;
 11 }que[MAXN],q1[MAXN],q2[MAXN];
 12 struct optnode
 13 {
 14     int opt,pos1,pos2,val;
 15 }opts[MAXN];
 16 int head,tail,cnt;
 17 int ans[MAXN];
 18 int n,nn,num[MAXN],q,jump[MAXN],realval[MAXN];
 19 int maxz;
 20 char opt[3];
 21 int tmp[MAXN];
 22 struct lsh
 23 {
 24     int val,id;
 25     bool operator <(lsh &t)const
 26     {
 27         return val<t.val;
 28     }
 29 }num2[MAXN];
 30 int tree[MAXN];
 31 void init(int x)
 32 {
 33     maxz=0;
 34     for(int i=1;i<=x;i++)
 35         num2[i].val=num[i],num2[i].id=i;
 36     sort(num2+1,num2+x+1);
 37     for(int i=1;i<=x;i++)
 38     {
 39         if(num2[i].val!=num2[i-1].val)
 40            ++maxz,realval[maxz]=num2[i].val;
 41         num[num2[i].id]=maxz;
 42 
 43     }
 44 }
 45 void add(int pos,int val)
 46 {
 47     while(pos<=n)
 48     {tree[pos]+=val;
 49     pos+=lowbit(pos);
 50     }
 51 }
 52 int getsum(int pos)
 53 {
 54     int tmp=0;
 55     while(pos)
 56     {
 57         tmp+=tree[pos];
 58         pos-=lowbit(pos);
 59     }
 60     return tmp;
 61 }
 62 void divide(int l,int r,int head,int tail)
 63 {
 64     if(head>tail)return;
 65     if(l==r)
 66     {
 67         for(int i=head;i<=tail;i++)
 68         {
 69             if(que[i].tp==3)
 70                 ans[que[i].addr]=l;
 71         }
 72         return;
 73     }
 74     int mid=(l+r)/2;
 75     for(int i=head;i<=tail;i++)
 76     {
 77         if(que[i].tp==1)if(num[que[i].val]<=mid)add(que[i].pos,1);
 78         if(que[i].tp==2)if(num[que[i].val]<=mid)add(que[i].pos,-1);
 79         if(que[i].tp==3)
 80             tmp[i]=getsum(que[i].ed)-getsum(que[i].pos-1);
 81     }
 82     for(int i=head;i<=tail;i++)
 83         {if(que[i].tp==1)if(num[que[i].val]<=mid)add(que[i].pos,-1);
 84          if(que[i].tp==2)if(num[que[i].val]<=mid)add(que[i].pos,1);
 85         }
 86 
 87         int l1=0,r1=0;
 88     for(int i=head;i<=tail;i++)
 89     {
 90         if(que[i].tp==3)
 91         {
 92             if(que[i].cur+tmp[i]>=que[i].val)
 93             q1[l1++]=que[i];
 94             else
 95             {
 96                 que[i].cur+=tmp[i];
 97                 q2[r1++]=que[i];
 98             }
 99         }
100         else
101         {
102             if(num[que[i].val]<=mid)
103                 q1[l1++]=que[i];
104             else q2[r1++]=que[i];
105         }
106     }
107     for(int i=0;i<l1;i++)que[head+i]=q1[i];
108     for(int i=0;i<r1;i++)que[head+l1+i]=q2[i];
109     divide(l,mid,head,head+l1-1);
110     divide(mid+1,r,head+l1,tail);
111 }
112 
113 int main()
114 {
115     int t1,t2,t3;
116     scanf("%d%d",&n,&q);
117     for(int i=1;i<=n;i++)scanf("%d",&num[i]),jump[i]=i;
118     int nn=n;
119     for(int i=1;i<=n;i++)
120     que[++tail].pos=i,que[tail].tp=1,que[tail].val=i;
121     for(int i=1;i<=q;i++)
122     {
123         scanf("%s",opt);
124         if(opt[0]=='Q')
125         {
126             scanf("%d %d %d",&t1,&t2,&t3);
127             que[++tail].tp=3,que[tail].pos=t1,que[tail].ed=t2,que[tail].val=t3;
128             que[tail].addr=cnt++;
129         }
130         else{
131             scanf("%d%d",&t1,&t2);
132             num[++nn]=t2;
133             que[++tail].tp=2,que[tail].pos=t1,que[tail].val=jump[t1];
134             que[++tail].tp=1,que[tail].pos=t1,que[tail].val=nn;
135             jump[t1]=nn;
136         }
137     }
138     init(nn);
139     divide(1,maxz,1,tail);
140     for(int i=0;i<cnt;i++)
141         printf("%d\n",realval[ans[i]]);
142     return 0;
143 }

 

posted on 2018-10-07 18:44  hefenghhhh  阅读(153)  评论(0编辑  收藏  举报