• [20200721NOIP提高组模拟T1]矩阵


    题目大意:

     给你一个数A,以及一串全是数字的字符串以构造矩阵C,C[i][j]=a[i]*a[j](a[k]表示字符串中第k位所代表的数字).请你求出权值之和恰好为A的子矩阵个数.

    solution:

     此题比较有意思.题目要我们求的答案即满足$(sum_{i=x}^{u}sum_{j=y}^{v} C[i][j]) ==A$的四元组[x,y,u,v]个数.接下来我们分析一下这个式子:$$sum_{i=x}^{u}sum_{j=y}^{v}C[i][j]=sum_{i=x}^{u}sum_{j=y}^{v} a[i] cdot a[j]=sum_{i=1}^{u}(a[i] cdot sum_{j=y}^{v}a[j])=sum_{i=x}^{u}a[i] cdot sum_{j=y}^{v}a[j]$$$$=(sum[u]-sum[x-1]) cdot (sum[v]-sum[y-1])$$其中sum[]数组为前缀和.由于n比较小$(nin 4000)$,所以我们可以n²预处理出前缀和之差,然后运用乘法原理组合即可.值得注意的是,当A==0时,由于0乘以任何数结果均为0,所以要特殊处理,0*0的矩阵被我们算了两次,所以要减掉一次.

    code:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<algorithm>
    #define R register
    #define next exnttttttttttttttttttttt
    #define debug puts("mlg")
    using namespace std;
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    inline ll read();
    inline void write(ll x);
    inline void writesp(ll x);
    inline void writeln(ll x);
    ll A;
    char wn;
    ll num[6000],n;
    ll used[150000],sum[150000];
    ll ans;
    int main(){
        A=read();
        wn=getchar();
        while(wn<'0'||wn>'9') wn=getchar();
        while(wn>='0'&&wn<='9'){
            num[++n]=wn-'0';wn=getchar();
        } 
        for(R ll i=1;i<=n;i++){
            sum[i]=sum[i-1]+num[i];
        }
        for(R ll i=1;i<=n;i++){
            for(R ll j=1;j<=i;j++){
                ++used[sum[i]-sum[j-1]];
            }
        }
        if(A==0){
            for(R ll i=0;i<=120000;i++) ans+=used[0]*used[i];
            ans<<=1;ans-=used[0]*used[0];
            writeln(ans);return 0;
        }
        for(R ll i=1;i<=120000;i++){
            if(A%i==0&&used[i]&&i*100000>=A){
                ans+=used[i]*used[A/i];
            }
        }
        writeln(ans);
    }
    inline ll read(){
        ll x=0,t=1;char ch=getchar();
        while(ch<'0'||ch>'9'){
            if(ch=='-') t=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9'){
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*t;
    }
    inline void write(ll x){
        if(x<0){putchar('-');x=-x;}
        if(x<=9){putchar(x+'0');return;}
        write(x/10);putchar(x%10+'0');
    }
    inline void writesp(ll x){
        write(x);putchar(' ');
    }
    inline void writeln(ll x){
        write(x);putchar('
    ');
    }

     

     

  • 相关阅读:
    Ajax随笔
    hdu 1395 2^x mod n = 1 暴力过~~最好学下欧拉定理~~~
    云计算设计模式(二)——断路器模式
    STL algorithm算法minmax,minmax_element(36)
    格式化时间
    django 带參数的 url
    Linux下 目录 压缩 解压缩 打包
    事实上就是为了玩
    Datazen配置
    HotSpot关联规则算法(2)-- 挖掘连续型和离散型数据
  • 原文地址:https://www.cnblogs.com/ylwtsq/p/13356111.html
Copyright © 2020-2023  润新知