粟粟的书架题解

粟粟的书架题解

第一次见到这种二合一的题,
开始的时候居然死磕二维主席树,
又是屈辱看题解系列,
其实比较好做
第一部分\(R, C≤200,M≤200000,1≤Pi,j≤1,000\)
这一部分可以用两个数组来记录:
\(num[i][j][k]\):代表1~i,1~j的矩形中小于等于k的书页数量,
\(v[i][j][k]\):代表1~i,1~j的矩形中小于等于k的书页页数之和。
二分最大书页页数,找到满足矩阵内v值大于给定h的最小值,输出对应num,
预处理时用二维前缀和的方式维护即可,

bool check(int x){return v[t3][t4][x]-v[t1-1][t4][x]+v[t1-1][t2-1][x]-v[t3][t2-1][x]>=t5;}
int ef(int l,int r){
    if(l==r) return l;
    int mid=(l+r+1)>>1;
    if(check(mid)) return ef(mid,r);
    return ef(l,mid-1);
int main(){
     if(r!=1){
       for(int i=1;i<=r;++i) for(int j=1;j<=c;++j){t=read(); for(int k=1;k<=1000;++k) num[i][j][k]=num[i-1][j][k]+num[i][j-1][k]-num[i-1][j-1][k]+(t>=k),v[i][j][k]=v[i-1][j][k]+v[i][j-1][k]-v[i-1][j-1][k]+(t>=k?t:0);}
       for(int i=1;i<=m;++i){t1=read(),t2=read(),t3=read(),t4=read(),t5=read(); if(!check(1)){printf("Poor QLW\n"); continue;} t=ef(1,1000),p=num[t3][t4][t+1]-num[t1-1][t4][t+1]+num[t1-1][t2-1][t+1]-num[t3][t2-1][t+1],q=v[t3][t4][t+1]-v[t1-1][t4][t+1]+v[t1-1][t2-1][t+1]-v[t3][t2-1][t+1],printf("%d\n",p+(t5-q-1)/t+1);}
        }
     }
}

后面r=1的情况:
同样二分,不过是二分第k大的书页页数的k,
我们可以用主席树维护第k大的页数之和,
直接上总代码吧:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=5e5+3006,K=202,M=1002;
int m,r,c,t,l=0,t1,t2,t3,t4,t5,num[K][K][M],v[K][K][M],p,q,cnt=0,rt[N],sum[N*12],son[N*12][2];
ll w[N<<4];
inline int read(){
   int T=0,F=1; char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-') F=-1; ch=getchar();}
   while(ch>='0'&&ch<='9')  T=(T<<3)+(T<<1)+(ch-48),ch=getchar();
   return F*T;
}
void update(int l,int r,int k,int &x,int y){
     if(!x) x=++cnt;
     if(l==r){sum[x]=sum[y]+1,w[x]=w[y]+l; return;}
     int mid=l+r>>1;
     if(k<=mid) update(l,mid,k,son[x][0],son[y][0]),son[x][1]=son[y][1];
     else update(mid+1,r,k,son[x][1],son[y][1]),son[x][0]=son[y][0];
     sum[x]=sum[son[x][0]]+sum[son[x][1]],w[x]=w[son[x][0]]+w[son[x][1]];
}
int query(int l,int r,int k,int x,int y){
   if(l==r) return min(sum[x]-sum[y],k)*l;
   int mid=l+r>>1;
   if(k<=sum[son[x][1]]-sum[son[y][1]]) return query(mid+1,r,k,son[x][1],son[y][1]);
   return w[son[x][1]]-w[son[y][1]]+query(l,mid,k-sum[son[x][1]]+sum[son[y][1]],son[x][0],son[y][0]);
}
bool check(int x){return v[t3][t4][x]-v[t1-1][t4][x]+v[t1-1][t2-1][x]-v[t3][t2-1][x]>=t5;}
int ef(int l,int r){
    if(l==r) return l;
    int mid=(l+r+1)>>1;
    if(check(mid)) return ef(mid,r);
    return ef(l,mid-1);
}
int ef2(int l,int r){
    if(l==r) return l;
    int mid=l+r>>1;
    if(query(1,1000,mid,rt[t4],rt[t2-1])>=t5) return ef2(l,mid);
    return ef2(mid+1,r);
}
int main(){
    r=read(),c=read(),m=read(),rt[0]=++cnt;
    if(r!=1){
       for(int i=1;i<=r;++i) for(int j=1;j<=c;++j){t=read(); for(int k=1;k<=1000;++k) num[i][j][k]=num[i-1][j][k]+num[i][j-1][k]-num[i-1][j-1][k]+(t>=k),v[i][j][k]=v[i-1][j][k]+v[i][j-1][k]-v[i-1][j-1][k]+(t>=k?t:0);}
       for(int i=1;i<=m;++i){t1=read(),t2=read(),t3=read(),t4=read(),t5=read(); if(!check(1)){printf("Poor QLW\n"); continue;} t=ef(1,1000),p=num[t3][t4][t+1]-num[t1-1][t4][t+1]+num[t1-1][t2-1][t+1]-num[t3][t2-1][t+1],q=v[t3][t4][t+1]-v[t1-1][t4][t+1]+v[t1-1][t2-1][t+1]-v[t3][t2-1][t+1],printf("%d\n",p+(t5-q-1)/t+1);}
    }
    else{
       for(int i=1;i<=c;++i) t=read(),update(1,1000,t,rt[i],rt[i-1]);
       for(int i=1;i<=m;++i){t1=read(),t2=read(),t3=read(),t4=read(),t5=read(); if(query(1,1000,t4-t2+1,rt[t4],rt[t2-1])<t5){printf("Poor QLW\n"); continue;} printf("%d\n",ef2(1,t4-t2+1));}
    }
    return 0;
}

原文地址:https://www.cnblogs.com/ljk123-de-bo-ke/p/11664021.html

时间: 2024-10-13 01:41:13

粟粟的书架题解的相关文章

BZOJ1926 [Sdoi2010]粟粟的书架 【主席树 + 二分 + 前缀和】

题目 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱的小朋友,她的爱好是画画和读书,尤其喜欢 Thomas H. Co rmen 的文章.粟粟家中有一个 R行C 列的巨型书架,书架的每一个位置都摆有一本书,上数第i 行.左数第j 列 摆放的书有Pi,j页厚.粟粟每天除了读书之外,还有一件必不可少的工作就是摘苹果,她每天必须摘取一个指定的 苹果.粟粟家果树上的苹果有的高.有的低,但无论如何凭粟粟自己的个头都难以摘到.不过她发现, 如果在脚 下放上几本书,就可以够着苹果:她同时注意到,对于第

1926: [Sdoi2010]粟粟的书架

1926: [Sdoi2010]粟粟的书架 Time Limit: 30 Sec  Memory Limit: 552 MBSubmit: 807  Solved: 321[Submit][Status][Discuss] Description 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱的小朋友,她的爱好是画画和读书,尤其喜欢 Thomas H. Co rmen 的文章.粟粟家中有一个 R行C 列的巨型书架,书架的每一个位置都摆有一本书,上数第i 行.左数第j 列 摆放的书有Pi,j

【BZOJ-1926】粟粟的书架 二分 + 前缀和 + 主席树

1926: [Sdoi2010]粟粟的书架 Time Limit: 30 Sec  Memory Limit: 552 MBSubmit: 616  Solved: 238[Submit][Status][Discuss] Description 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱的小朋友,她的爱好是画画和读书,尤其喜欢 Thomas H. Cormen 的文章.粟粟家中有一个 R行C 列的巨型书架,书架的每一个位置都摆有一本书,上数第i 行.左数第j 列摆放的书有Pi,j页厚

【BZOJ1926】【SDOI2010】粟粟的书架 [主席树]

粟粟的书架 Time Limit: 30 Sec  Memory Limit: 552 MB[Submit][Status][Discuss] Description 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱的小朋友,她的爱好是画画和读书,尤其喜欢 Thomas H. Cormen 的文章. 粟粟家中有一个 R行C列 的巨型书架,书架的每一个位置都摆有一本书,上数第 i 行.左数第 j 列摆放的书有Pi,j页厚. 粟粟每天除了读书之外,还有一件必不可少的工作就是摘苹果,她每天必须摘取

bzoj1926 [Sdoi2010]粟粟的书架

Description 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱的小朋友,她的爱好是画画和读书,尤其喜欢 Thomas H. Cormen 的文章.粟粟家中有一个 R行C 列的巨型书架,书架的每一个位置都摆有一本书,上数第i 行.左数第j 列摆放的书有Pi,j页厚.粟粟每天除了读书之外,还有一件必不可少的工作就是摘苹果,她每天必须摘取一个指定的苹果.粟粟家果树上的苹果有的高.有的低,但无论如何凭粟粟自己的个头都难以摘到.不过她发现, 如果在脚下放上几本书,就可以够着苹果:她同时注意到

【刷题】BZOJ 1926 [Sdoi2010]粟粟的书架

Description 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱的小朋友,她的爱好是画画和读书,尤其喜欢 Thomas H. Cormen 的文章.粟粟家中有一个 R行C 列的巨型书架,书架的每一个位置都摆有一本书,上数第i 行.左数第j 列摆放的书有Pi,j页厚.粟粟每天除了读书之外,还有一件必不可少的工作就是摘苹果,她每天必须摘取一个指定的苹果.粟粟家果树上的苹果有的高.有的低,但无论如何凭粟粟自己的个头都难以摘到.不过她发现, 如果在脚下放上几本书,就可以够着苹果:她同时注意到

[Sdoi2010]粟粟的书架

Description 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱的小朋友,她的爱好是画画和读书,尤其喜欢 Thomas H. Cormen 的文章.粟粟家中有一个 R行C 列的巨型书架,书架的每一个位置都摆有一本书,上数第i 行.左数第j 列摆放的书有Pi,j页厚.粟粟每天除了读书之外,还有一件必不可少的工作就是摘苹果,她每天必须摘取一个指定的苹果.粟粟家果树上的苹果有的高.有的低,但无论如何凭粟粟自己的个头都难以摘到.不过她发现, 如果在脚下放上几本书,就可以够着苹果:她同时注意到

[SDOI2010]粟粟的书架 [主席树]

[SDOI2010]粟粟的书架 考虑暴力怎么做 显然是提取出来 (x2-x1+1)*(y2-y1+1) 个数字拿出来 然后从大到小排序 然后就可以按次取数了- 然而接下来看数据范围 \(50\%\ r,c\leq 200\) \(50\%\ r=1,c\leq 5*10^5\) 值域 \(\in [1,1000]\) 对于前 50% 可以用个前缀和搞定- 令 \(sum_{i,j,k}\) 为 大于 k 的前缀和 \(num_{i,j,k}\) 为 大于 k 的前缀和数量 然后愉快的二分? 另外

AC日记——[Sdoi2010]粟粟的书架 bzoj 1926

1926 思路: 主席树+二分水题: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 500005 #define maxr 205 #define maxn_ maxn*13 #define FalseAns "Poor QLW" int n,m,q,lc[maxn_],rc[maxn_],num[maxn_],ci[maxn_],tot,root[maxn]; int ai[maxn],bi[