整体二分

来源:互联网 发布:网络诈骗主题班会 编辑:程序博客网 时间:2024/04/24 18:34

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];elseq[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;}


0 0
原创粉丝点击