动态修改求区间K大。
整体二分是一个神奇的东西: http://www.cnblogs.com/zig-zag/archive/2013/04/18/3027707.html
入门:
一般的主席树都挂了,而且又难写。
南神的分析:http://blog.csdn.net/hdu2014/article/details/47834431 ORZ
然后对着板子写了一份:
1 #include<iostream>
2 #include<cstdio>
3 #include<algorithm>
4 #include<cmath>
5 #include<cstring>
6 #define maxn 450000
7 #define inf 2000000000
8 typedef long long ll;
9
10 using namespace std;
11 struct query
12 {
13 int x,y,k,s,tp,cur;
14 }q[maxn],q1[maxn],q2[maxn];
15 int a[maxn],ans[maxn],tmp[maxn],t[maxn];
16 int n,m,num,cnt;
17
18 void add(int x,int y)
19 {
20 for (int i=x;i<=n;i+=i&(-i)) t[i]+=y;
21 }
22 int ask(int x)
23 {
24 int s=0;
25 for (int i=x;i>0;i-=i&(-i)) s+=t[i];
26 return s;
27 }
28
29 void divide(int head,int tail,int l,int r)
30 {
31 if (head>tail) return;
32 if (l==r)
33 {
34 for (int i=head;i<=tail;i++)
35 if (q[i].tp==3) ans[q[i].s]=l;
36 return;
37 }
38 int mid=(l+r)>>1;
39 for (int i=head;i<=tail;i++)
40 {
41 if (q[i].tp==1&&q[i].y<=mid) add(q[i].x,1);
42 else
43 if (q[i].tp==2&&q[i].y<=mid) add(q[i].x,-1);
44 else
45 if (q[i].tp==3) tmp[i]=ask(q[i].y)-ask(q[i].x-1);
46 }
47
48 for (int i=head;i<=tail;i++)
49 {
50 if (q[i].tp==1&&q[i].y<=mid) add(q[i].x,-1);
51 else
52 if (q[i].tp==2&&q[i].y<=mid) add(q[i].x,1);
53 }
54
55 int l1,l2;
56 l1=l2=0;
57 for (int i=head;i<=tail;i++)
58 if (q[i].tp==3)
59 {
60 if (q[i].cur+tmp[i]>q[i].k-1) q1[++l1]=q[i];
61 else
62 {
63 q[i].cur+=tmp[i];
64 q2[++l2]=q[i];
65 }
66 }
67 else
68 {
69 if (q[i].y<=mid) q1[++l1]=q[i];
70 else q2[++l2]=q[i];
71 }
72
73 for (int i=1;i<=l1;i++) q[head+i-1]=q1[i];
74 for (int i=1;i<=l2;i++) q[head+i+l1-1]=q2[i];
75 divide(head,head+l1-1,l,mid);
76 divide(head+l1,tail,mid+1,r);
77 }
78
79 int main()
80 {
81 while (scanf("%d",&n)!=EOF)
82 {
83 for (int i=0;i<=n;i++) t[i]=0;
84 memset(q,0,sizeof(q));
85 memset(q1,0,sizeof(q1));
86 memset(q2,0,sizeof(q2));
87
88 num=cnt=0;
89 for (int i=1;i<=n;i++)
90 {
91 scanf("%d",&a[i]);
92 q[++num].x=i,q[num].y=a[i];
93 q[num].tp=1;q[num].s=0;
94 }
95 int ss,x,y,z;
96 scanf("%d",&m);
97 for (int i=1;i<=m;i++)
98 {
99 scanf("%d",&ss);
100 if (ss==2)
101 {
102 scanf("%d%d%d",&x,&y,&z);
103 q[++num].x=x,q[num].y=y,q[num].k=z;
104 q[num].tp=3;q[num].s=++cnt;
105 }
106 else
107 {
108 scanf("%d%d",&x,&y);
109 q[++num].x=x;
110 q[num].y=a[x];
111 q[num].tp=2;q[num].s=0;
112 q[++num].x=x,q[num].y=y;
113 q[num].tp=1,q[num].s=0;
114 a[x]=y;
115 }
116 }
117
118 divide(1,num,0,inf);
119 for (int i=1;i<=cnt;i++)
120 printf("%d ",ans[i]);
121 }
122 return 0;
3 #include<algorithm>
4 #include<cmath>
5 #include<cstring>
6 #define maxn 450000
7 #define inf 2000000000
8 typedef long long ll;
9
10 using namespace std;
11 struct query
12 {
13 int x,y,k,s,tp,cur;
14 }q[maxn],q1[maxn],q2[maxn];
15 int a[maxn],ans[maxn],tmp[maxn],t[maxn];
16 int n,m,num,cnt;
17
18 void add(int x,int y)
19 {
20 for (int i=x;i<=n;i+=i&(-i)) t[i]+=y;
21 }
22 int ask(int x)
23 {
24 int s=0;
25 for (int i=x;i>0;i-=i&(-i)) s+=t[i];
26 return s;
27 }
28
29 void divide(int head,int tail,int l,int r)
30 {
31 if (head>tail) return;
32 if (l==r)
33 {
34 for (int i=head;i<=tail;i++)
35 if (q[i].tp==3) ans[q[i].s]=l;
36 return;
37 }
38 int mid=(l+r)>>1;
39 for (int i=head;i<=tail;i++)
40 {
41 if (q[i].tp==1&&q[i].y<=mid) add(q[i].x,1);
42 else
43 if (q[i].tp==2&&q[i].y<=mid) add(q[i].x,-1);
44 else
45 if (q[i].tp==3) tmp[i]=ask(q[i].y)-ask(q[i].x-1);
46 }
47
48 for (int i=head;i<=tail;i++)
49 {
50 if (q[i].tp==1&&q[i].y<=mid) add(q[i].x,-1);
51 else
52 if (q[i].tp==2&&q[i].y<=mid) add(q[i].x,1);
53 }
54
55 int l1,l2;
56 l1=l2=0;
57 for (int i=head;i<=tail;i++)
58 if (q[i].tp==3)
59 {
60 if (q[i].cur+tmp[i]>q[i].k-1) q1[++l1]=q[i];
61 else
62 {
63 q[i].cur+=tmp[i];
64 q2[++l2]=q[i];
65 }
66 }
67 else
68 {
69 if (q[i].y<=mid) q1[++l1]=q[i];
70 else q2[++l2]=q[i];
71 }
72
73 for (int i=1;i<=l1;i++) q[head+i-1]=q1[i];
74 for (int i=1;i<=l2;i++) q[head+i+l1-1]=q2[i];
75 divide(head,head+l1-1,l,mid);
76 divide(head+l1,tail,mid+1,r);
77 }
78
79 int main()
80 {
81 while (scanf("%d",&n)!=EOF)
82 {
83 for (int i=0;i<=n;i++) t[i]=0;
84 memset(q,0,sizeof(q));
85 memset(q1,0,sizeof(q1));
86 memset(q2,0,sizeof(q2));
87
88 num=cnt=0;
89 for (int i=1;i<=n;i++)
90 {
91 scanf("%d",&a[i]);
92 q[++num].x=i,q[num].y=a[i];
93 q[num].tp=1;q[num].s=0;
94 }
95 int ss,x,y,z;
96 scanf("%d",&m);
97 for (int i=1;i<=m;i++)
98 {
99 scanf("%d",&ss);
100 if (ss==2)
101 {
102 scanf("%d%d%d",&x,&y,&z);
103 q[++num].x=x,q[num].y=y,q[num].k=z;
104 q[num].tp=3;q[num].s=++cnt;
105 }
106 else
107 {
108 scanf("%d%d",&x,&y);
109 q[++num].x=x;
110 q[num].y=a[x];
111 q[num].tp=2;q[num].s=0;
112 q[++num].x=x,q[num].y=y;
113 q[num].tp=1,q[num].s=0;
114 a[x]=y;
115 }
116 }
117
118 divide(1,num,0,inf);
119 for (int i=1;i<=cnt;i++)
120 printf("%d ",ans[i]);
121 }
122 return 0;
123 }
2s左右。