整体二分
来源:互联网 发布:网络诈骗主题班会 编辑:程序博客网 时间: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
- 整体二分
- 整体二分
- 整体二分
- 整体二分
- 整体二分
- 整体二分
- 整体二分(二分进阶)
- BZOJ1901【整体二分】
- BZOJ2527【整体二分】
- 整体二分入门
- 复习一下整体二分
- 【bzoj2527】Meteors【整体二分】
- POJ 2104【整体二分】
- 整体二分小结
- 【辅助算法】整体二分
- 整体二分初步
- POJ2104 整体二分、树套树
- hdu5808 整体二分
- ListView的item加载几种不同布局
- Ubuntu启动时进入禁止grub界面
- 离线安装m2eclipse
- APP微信快捷登录
- 分享一个连接
- 整体二分
- 秒杀多线程第十篇 生产者消费者问题
- Android图片加载缓存库<3>
- Android4.4 meminfo 实现分析
- BZOJ1053: [HAOI2007]反素数ant
- JS之块级作用域
- ffplay的音视频同步分析
- https+ssl详解
- Swift中的Function