矩形

题目

给定一个由数字(0-9)构成的字符串s。我们可以由此定义出size(s) * size(s) 大
小的矩阵b,其中b[i][j] = s[i] * s[j];请问在这个矩阵b中,有多少子矩形满足其中的b[i][j]的和为另一个给定的数字a。


分析

Size(s)≤ 4000,注意到 a = sum[x1..x2] * sum[y1..y2],那么 sum[x1..x2]和sum[y1..y2]都要是 a 的约数,不失一般性,我们枚举 sum[x1..x2]的值,那么我们所关心的就是符合 sum[x1..x2]这样的和符合 sum[y1..y2] = a / sum[x1..x2]那样的值分别有多少个,把这两个数乘起来进行累加,即为答案;但是,a 可以取到 0,上述方法即不成立,所以需要特殊考虑;当sum[x1..x2] = 0 时,sum[y1..y2]可以为任意值;


程序

#include<cstring>
#include<iostream>
using namespace std;
int n,l;
int a[50005],sum[50005];
long long ans;
char s[50005];
int main(){
    cin>>n;
    cin>>s;
    l=strlen(s);
    for(int i=1;i<=l;i++)
        a[i]=a[i-1]+s[i-1]-'0';      
    for(int i=1;i<=l;i++)
        for(int j=i;j<=l;j++)
            sum[a[j]-a[i-1]]++;
    if (n!=0)
        for(int i=1;i<=l;i++)
            for(int j=i;j<=l;j++){
                int t=a[j]-a[i-1];
                if (t==0) continue;
                if (n%t!=0) continue;
                if (n/t>50005) continue;
                ans+=sum[n/t];
            }
        else
            for(int i=1;i<=l;i++)
                for(int j=i;j<=l;j++){
                    int t=a[j]-a[i-1];
                    if(t==0) ans+=l*(l+1)/2;  
                        else ans+=sum[0];
                }
    cout<<ans<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值