[前缀和][枚举] Jzoj P5842 a

Description
给定一个n*m 的 01 矩阵,求包含[l,r]个 1 的子矩形个数。
 
 
Input
第一行,两个正整数n,m。
接下来n 行,每行一个长度为 m 的 01 串,表示给定的矩阵。接下来一行,两个自然数 l,r。
 
Output
第一行,一个整数代表答案。
 
 
Sample Input
见下发文件
Sample Output
见下发文件
 
 
Data Constraint

 

 

题解

  • 注意到n很小,那么可以n^2枚举矩阵的上下边界
  • 然后两个指针,x和y,记录到刚好小于l,和刚好大于r的
  • 算一波方案数就好了

代码

 1 #include <cstdio>
 2 using namespace std;
 3 char s[50010];
 4 long long n,m,i,j,p[50010],a[40][50010],sum[40][50010],q[50010],ans,k,l,r;
 5 int main()
 6 {
 7     freopen("a.in","r",stdin);
 8     freopen("a.out","w",stdout);
 9     scanf("%lld%lld",&n,&m);
10     for (int i=1;i<=n;i++)
11     {
12         scanf("%s\n",s+1);
13         for (int j=1;j<=m;j++)
14         {
15             a[i][j]=s[j]-'0';
16             sum[i][j]=sum[i-1][j]+a[i][j];
17         }
18     }
19     scanf("%lld%lld\n",&l,&r);
20     for (int i=1;i<=n;i++)
21         for (int j=i;j<=n;j++)
22         {
23             long long x=0,y=0;
24             for (int k=1;k<=m;k++)
25             {
26                 p[k]=sum[j][k]-sum[i-1][k];
27                 q[k]=q[k-1]+p[k];
28             }
29             for (int k=1;k<=m;k++)
30             {
31                 while (q[k]-q[x]>=l&&x<k) x++;
32                 while (q[k]-q[y]>r&&y<k) y++;
33                 ans+=x-y;
34             } 
35         }
36     printf("%lld\n",ans);
37     return 0;
38 } 

 

转载于:https://www.cnblogs.com/Comfortable/p/9526497.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值