bzoj1926: [Sdoi2010]粟粟的书架

来源:互联网 发布:网络机顶盒如何使用 编辑:程序博客网 时间:2024/05/17 22:24

AC:100题

这是一道2合一水题。。。

看数据范围:

对于 50%的数据,满足 R, C≤200,M≤200,000 

另有 50%的数据,满足 R=1,C≤500,000,M≤20,000

所以对于50%的数据用a[i][j][k]表示比k大的数的个数,b[i][j][k]表示比k大的数的和。O(1000*RC)预处理+O(log 1000)询问水过。

另50%的数据考虑主席树,v[i]表示i节点对应区间个数,s[i]表示区间和,O(C log 1000)预处理+O(log 1000)询问。

lych大说他可能有一种通用方法,然而空间不够?

卡着空间过了。。。//把a[i][j][k]变成a[k][i][j]后居然会变慢!无法理解。。。

#include<iostream>#include<cstdio>using namespace std;int n,m,T,a[210][210][1010],b[210][210][1010],c[210][210],x1,y1,x2,y2,h;int t,rt[550000],ls[11000000],rs[11000000],v[11000000],s[11000000],cnt;int read(){char c=getchar();int x=0;while (c<'0'||c>'9') c=getchar();while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();return x;}void work1(){for (int i=1;i<=n;i++)for (int j=1;j<=m;j++)c[i][j]=read();for (int i=1;i<=n;i++)for (int j=1;j<=m;j++)for (int k=1;k<=1000;k++){a[i][j][k]=a[i][j-1][k]+a[i-1][j][k]-a[i-1][j-1][k];b[i][j][k]=b[i][j-1][k]+b[i-1][j][k]-b[i-1][j-1][k];if (c[i][j]>=k) a[i][j][k]++,b[i][j][k]+=c[i][j];}while (T--){x1=read(),y1=read(),x2=read(),y2=read(),h=read();int L=0,R=1001;x1--;y1--;while (L+1<R){int mid=(L+R)>>1;if (b[x1][y1][mid]+b[x2][y2][mid]-b[x2][y1][mid]-b[x1][y2][mid]>=h) L=mid; else R=mid;}if (L==0) puts("Poor QLW");else{int sum1=b[x1][y1][L]+b[x2][y2][L]-b[x2][y1][L]-b[x1][y2][L]-h;int sum2=a[x1][y1][L]+a[x2][y2][L]-a[x2][y1][L]-a[x1][y2][L];printf("%d\n",sum2-sum1/L);}}}void add(int l,int r,int x,int &y,int k){y=++cnt;v[y]=v[x]+1;s[y]=s[x]+k;if (l==r) return;int mid=(l+r)>>1;if (k<=mid) rs[y]=rs[x],add(l,mid,ls[x],ls[y],k);else ls[y]=ls[x],add(mid+1,r,rs[x],rs[y],k);}int qry(int x,int y,int k){int l=1,r=1000,used=0;x=rt[x-1];y=rt[y];if (s[y]-s[x]<h) return -1;while (l<r){int mid=(l+r)>>1,t=s[rs[y]]-s[rs[x]];if (t<k) {used+=v[rs[y]]-v[rs[x]];k-=t;r=mid;x=ls[x];y=ls[y];}else {l=mid+1;x=rs[x];y=rs[y];}}used+=(k+l-1)/l;return used;}void work2(){for (int i=1;i<=m;i++)t=read(),add(1,1000,rt[i-1],rt[i],t);while(T--){x1=read(),y1=read(),x2=read(),y2=read(),h=read();int Ans=qry(y1,y2,h);if (Ans==-1)puts("Poor QLW");else printf("%d\n",Ans);}}int main(){n=read(),m=read(),T=read();if (n!=1)work1();else work2();return 0;}



0 0
原创粉丝点击