OrzOrzOrz
OTZOTZOTZ
%%%%%%%%%%%%
长跪不起
http://www.cnblogs.com/zig-zag/archive/2013/04/18/3027707.html
就在本蒟蒻还在为树套树套树套树怎么写而发愁时(反正就是不会写+懒得写),突然发现了这么个利器。
哈哈哈哈哈哈哈哈哈哈哈哈哈。
以后完全不用写什么高端的数据结构了。
统统离线好了(什么强制在线?不做)。
顺便做了下ZOJ2112和POJ2104(一开始狂TLE发现数组开小了,竟然没RE。。。)
一个是动态区间第K大,一个是静态区间第K大。
全都BIT+整体二分,短小精悍。
ZOJ2112:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=50000+5;
const int M=10000+5;
const int inf=1e9;
struct Query{
int x,y,k,tp,id,cur;
}q[N+M*2],q1[N+M*2],q2[N+M*2];
int a[N],ans[M],tmp[N+M*2],c[N];
int n,m,cnt,num;
inline int lowbit(int x){return x&-x;}
void add(int x,int v){
for(;x<=n;x+=lowbit(x))c[x]+=v;
}
int sum(int x){
int ret=0;
for(;x>0;x-=lowbit(x))ret+=c[x];
return ret;
}
void divide(int head,int tail,int l,int r){
if(head>tail)return;
if(l==r){
for(int i=head;i<=tail;i++)
if(q[i].tp==3)ans[q[i].id]=l;
return;
}
int mid=l+r>>1;
for(int i=head;i<=tail;i++)
if(q[i].tp==1&&q[i].y<=mid) add(q[i].x,1);
else
if(q[i].tp==2&&q[i].y<=mid) add(q[i].x,-1);
else
if(q[i].tp==3) tmp[i]=sum(q[i].y)-sum(q[i].x-1);
for(int i=head;i<=tail;i++)
if(q[i].tp==1&&q[i].y<=mid) add(q[i].x,-1);
else
if(q[i].tp==2&&q[i].y<=mid) add(q[i].x,1);
int l1=0,l2=0;
for(int i=head;i<=tail;i++)
if(q[i].tp==3){
if(q[i].cur+tmp[i]>q[i].k-1)q1[++l1]=q[i];
else q[i].cur+=tmp[i],q2[++l2]=q[i];
}else{
if(q[i].y<=mid)q1[++l1]=q[i];
else q2[++l2]=q[i];
}
for(int i=1;i<=l1;i++)q[head+i-1]=q1[i];
for(int i=1;i<=l2;i++)q[head+i-1+l1]=q2[i];
divide(head,head+l1-1,l,mid);
divide(head+l1,tail,mid+1,r);
}
int main(){
int X;scanf("%d",&X);
while(X--){
scanf("%d%d",&n,&m);
cnt=0;num=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
q[++cnt].x=i;q[cnt].y=a[i];q[cnt].tp=1;
}
int x,y,k;char opt[10];
for(int i=1;i<=m;i++){
scanf("%s",opt);
if(opt[0]=='Q'){
scanf("%d%d%d",&x,&y,&k);
q[++cnt].x=x;q[cnt].y=y;q[cnt].k=k;q[cnt].cur=0;q[cnt].id=++num;q[cnt].tp=3;
}else{
scanf("%d%d",&x,&y);
q[++cnt].x=x;q[cnt].y=a[x];q[cnt].tp=2;
q[++cnt].x=x;q[cnt].y=y;q[cnt].tp=1;
a[x]=y;
}
}
divide(1,cnt,0,inf);
for(int i=1;i<=num;i++)
printf("%d\n",ans[i]);
}
return 0;
}
POJ2104:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int inf=1e9;
const int N=100000+5;
const int M=5000+5;
struct Query{
int x,y,k,id,tp,cur;
}q[N+M],q1[N+M],q2[N+M];
int ans[M],tmp[N+M],d[N];
int n,m,cnt;
inline int lowbit(int x){return x&-x;}
void add(int x,int v){
for(;x<=n;x+=lowbit(x))d[x]+=v;
}
int sum(int x){
int ret=0;
for(;x>0;x-=lowbit(x))ret+=d[x];
return ret;
}
void divide(int head,int tail,int l,int r){
if(head>tail)return;
if(l==r){
for(int i=head;i<=tail;i++)
if(q[i].tp==2)ans[q[i].id]=l;
return;
}
int mid=l+(r-l)/2;
for(int i=head;i<=tail;i++)
if(q[i].tp==1&&q[i].y<=mid)add(q[i].x,1);
else if(q[i].tp==2)tmp[i]=sum(q[i].y)-sum(q[i].x-1);
for(int i=head;i<=tail;i++)
if(q[i].tp==1&&q[i].y<=mid)add(q[i].x,-1);
int l1=0,l2=0;
for(int i=head;i<=tail;i++)
if(q[i].tp==2){
if(q[i].cur+tmp[i]>q[i].k-1)q1[++l1]=q[i];
else q[i].cur+=tmp[i],q2[++l2]=q[i];
}else{
if(q[i].y<=mid)q1[++l1]=q[i];
else q2[++l2]=q[i];
}
for(int i=1;i<=l1;i++)q[head+i-1]=q1[i];
for(int i=1;i<=l2;i++)q[head+i+l1-1]=q2[i];
divide(head,head+l1-1,l,mid);
divide(head+l1,tail,mid+1,r);
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
q[++cnt].x=i;scanf("%d",&q[cnt].y);
q[cnt].tp=1;
}
for(int i=1;i<=m;i++){
q[++cnt].id=i;
scanf("%d%d%d",&q[cnt].x,&q[cnt].y,&q[cnt].k);
q[cnt].tp=2;
}
divide(1,cnt,-inf,inf);
for(int i=1;i<=m;i++)
printf("%d\n",ans[i]);
return 0;
}