bzoj 1926: [Sdoi2010]粟粟的书架
2016-03-18 05:54
525 查看
#include<cstdio> #include<iostream> #define N 201 #define M 500008 using namespace std; int cnt,r,c,m,ls[20*M],rs[20*M],root[M],ans,sum[20*M],sum1[20*M],shu,num[1008] ,num1[1008] ; void jia(int l,int r,int x,int &y,int v) { y=++cnt; sum[y]=sum[x]+v; sum1[y]=sum1[x]+1; if(l==r) return; ls[y]=ls[x]; rs[y]=rs[x]; int mid=(l+r)>>1; if(v<=mid) jia(l,mid,ls[x],ls[y],v); else jia(mid+1,r,rs[x],rs[y],v); return; } int xun(int a1,int a2,int l,int r,int v) { if(!a1) return 0; if(l>=v) { shu-=sum[a1]-sum[a2]; return sum1[a1]-sum1[a2]; } int s=0,mid=(l+r)>>1; if(mid>=v) s+=xun(ls[a1],ls[a2],l,mid,v); s+=xun(rs[a1],rs[a2],mid+1,r,v); return s; } void solve1() { for(int i=1;i<=c;i++) { int a1; scanf("%d",&a1); jia(1,1000,root[i-1],root[i],a1); } for(int i=1;i<=m;i++) { int x0,y0,x1,y1,v; scanf("%d%d%d%d%d",&x0,&y0,&x1,&y1,&v); int l=0,r=1000,mid=(l+r)>>1,b1,md,md1; ans=0; for(;l<=r;) { shu=v; b1=xun(root[y1],root[y0-1],1,1000,mid); if(shu<=0) { md1=v-shu; md=mid; ans=b1; l=mid+1; } else r=mid-1; mid=(l+r)>>1; } if(!ans) printf("Poor QLW\n"); else { int a1; r=xun(root[y1],root[y0-1],1,1000,md+1); r=ans-r; l=0; mid=(l+r)>>1; for(;l<=r;) { if(md1-mid*md>=v) { a1=ans-mid; l=mid+1; } else r=mid-1; mid=(l+r)>>1; } printf("%d\n",a1); } } return; } void solve2() { for(int i=1;i<=r;i++) for(int j=1;j<=c;j++) { int a1; scanf("%d",&a1); for(int k=0;k<=1000;k++) { num[k][i][j]=(num[k][i][j-1]+num[k][i-1][j]-num[k][i-1][j-1]); num1[k][i][j]=(num1[k][i][j-1]+num1[k][i-1][j]-num1[k][i-1][j-1]); if(a1>=k) { num[k][i][j]+=a1; num1[k][i][j]++; } } } for(int i=1;i<=m;i++) { int x0,y0,x1,y1,v; scanf("%d%d%d%d%d",&x0,&y0,&x1,&y1,&v); int l=0,r=1000,mid=(l+r)>>1,tm=0,tm1=0,tm2=0; for(;l<=r;) { if(num[mid][x1][y1]-num[mid][x1][y0-1]-num[mid][x0-1][y1]+num[mid][x0-1][y0-1]>=v) { tm=num1[mid][x1][y1]-num1[mid][x1][y0-1]-num1[mid][x0-1][y1]+num1[mid][x0-1][y0-1]; tm1=mid; l=mid+1; } else r=mid-1; mid=(l+r)>>1; } if(!tm) printf("Poor QLW\n"); else { tm2=num[tm1][x1][y1]-num[tm1][x1][y0-1]-num[tm1][x0-1][y1]+num[tm1][x0-1][y0-1]; l=0,r=num1[tm1+1][x1][y1]-num1[tm1+1][x1][y0-1]-num1[tm1+1][x0-1][y1]+num1[tm1+1][x0-1][y0-1]; r=tm-r; mid=(l+r)>>1; for(;l<=r;) { if(tm2-mid*tm1>=v) { ans=tm-mid; l=mid+1; } else r=mid-1; mid=(l+r)>>1; } printf("%d\n",ans); } } return; } int main() { scanf("%d%d%d",&r,&c,&m); if(r==1) solve1(); else solve2(); return 0; }
两种情况 对于R,C<=200,用前缀和暴力二分,对于另外的数据,在主席树上二分。
相关文章推荐
- 生活中如何说服别人
- bzoj 1923: [Sdoi2010]外星千足虫
- bzoj 1922: [Sdoi2010]大陆争霸
- bzoj 1911: [Apio2010]特别行动队
- 抽象类
- Python环境搭建
- 10.N个整数中查找是否相加为K[深度搜索]
- PCL Notes 1
- sizeof()用法汇总
- [复习]jQuery知识点
- Start as a fresh.....
- 仿Smarty替换模板标签时遇到的问题
- 使用GPG对文件进行加密解密批处理
- 黑客们很喜欢骇客交锋,虽然本片不被影评人认可
- 《愤怒的小鸟2》制作公司再裁人260人
- navicat 10.1.7的序列号
- POJ 3122 & 3258 & 3273 #二分
- POJ 1905 Expanding Rods#二分
- POJ 1845 Sumdiv#质因数分解+二分
- 【菜鸟手打js】@弹出遮罩层显示大图之二