1. 程式人生 > >洛谷P2468 SDOI 2010 粟粟的書架

洛谷P2468 SDOI 2010 粟粟的書架

etc con ace print define getchar() zoj -- highlight

題意:給你一個矩形書架,每個點是這本書的頁數,每次詢問(x1,y1)(x2,y2)這個小矩形裏最少需要取幾本書使得頁數和等於Hi。

題解:小數據二位前綴和預處理+二分答案,大數據一行所以用主席樹做,感覺數組開得玄學,洛谷上很好過,BZOJ經歷了TLE->MLE->CE emmmmm,找不到CE在哪裏。

#include<bits/stdc++.h>
#define long long ll
using namespace std;
const int maxn=5e5+100;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
int n,m,vv;
int val[205][205][1005];
int sum[205][205][1005];
int cc[1005];
int page[205][205];
struct node
{
    int l,r;
    int val,sum;
}no[maxn*20];
inline int get_val(int x1,int y1,int x2,int y2,int k)
{
    return val[x2][y2][k]-val[x1-1][y2][k]-val[x2][y1-1][k]+val[x1-1][y1-1][k];
}
inline int get_sum(int x1,int y1,int x2,int y2,int k)
{
    return sum[x2][y2][k]-sum[x1-1][y2][k]-sum[x2][y1-1][k]+sum[x1-1][y1-1][k];
}
int rs,p,q,pp,qq;
inline void work1()
{
    int tmp=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            page[i][j]=read();
            cc[page[i][j]]++;
            if(page[i][j]>tmp)tmp=page[i][j];
        }
    }
    for(int k=0;k<=tmp;k++)
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                val[i][j][k]=val[i-1][j][k]+val[i][j-1][k]-val[i-1][j-1][k]+(page[i][j]>=k?page[i][j]:0);
                sum[i][j][k]=sum[i-1][j][k]+sum[i][j-1][k]-sum[i-1][j-1][k]+(page[i][j]>=k?1:0);
            }
        }
    }
    while(vv--)
    {
        p=read();q=read();pp=read();qq=read();rs=read();
        if(get_val(p,q,pp,qq,0)<rs)
        {
            printf("Poor QLW\n");
            continue;
        }
        int l=1,r=tmp,ans=-1;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(get_val(p,q,pp,qq,mid)>=rs)l=mid+1,ans=mid;
            else r=mid-1;
        }
        if(ans==-1)printf("Poor QLW\n");
        else{
            int res=get_sum(p,q,pp,qq,ans)-(get_val(p,q,pp,qq,ans)-rs)/ans;
            printf("%d\n",res);
        }
    }
}
int cnt=0;
int ssq[maxn];
int root[maxn];
void build(int &x,int l,int r)
{
    x=++cnt;
    no[x].val=no[x].sum=0;
    if(l==r)return;
    int mid=(l+r)>>1;
    build(no[x].l,l,mid);
    build(no[x].r,mid+1,r);
}
void insertt(int&x,int pre,int l,int r,int pl)
{
    x=++cnt;
    no[x]=no[pre];
    no[x].sum++;
    no[x].val+=pl;
    if(l==r)return ;
    int mid=(l+r)>>1;
    if(pl<=mid)insertt(no[x].l,no[pre].l,l,mid,pl);
    else insertt(no[x].r,no[pre].r,mid+1,r,pl);
}
int query(int x,int pre,int l,int r,int rs)
{
    if(l==r)
    {
        if(rs%l==0)return rs/l;
        return rs/l+1;
    }
    int mid=(l+r)>>1;
    int tmp=no[no[x].r].val-no[no[pre].r].val;
    int ans=0;
    if(tmp<rs)
    {
        rs-=tmp;
        ans+=no[no[x].r].sum-no[no[pre].r].sum;
        ans+=query(no[x].l,no[pre].l,l,mid,rs);
    }
    else{
        ans+=query(no[x].r,no[pre].r,mid+1,r,rs);
    }
    return ans;
}
void work2()
{
    int maxx=0;
    for(int i=1;i<=m;i++)ssq[i]=read(),maxx=max(ssq[i],maxx);
    build(root[0],1,maxx);
    for(int i=1;i<=m;i++)insertt(root[i],root[i-1],1,maxx,ssq[i]);
    while(vv--)
    {
        p=read();q=read();pp=read();qq=read();rs=read();
        if(no[root[qq]].val-no[root[q-1]].val<rs)
        {
            printf("Poor QLW\n");
            continue;
        }
        printf("%d\n",query(root[qq],root[q-1],1,maxx,rs));
    }
}
int main()
{
    n=read();m=read();vv=read();
    if(n==1)work2();
    else work1();
}

  

洛谷P2468 SDOI 2010 粟粟的書架