zoukankan      html  css  js  c++  java
  • [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('
    ');
    }

     

     

  • 相关阅读:
    详解consul的安装和配置
    vs2017
    Android Bitmap 和 ByteArray的互相转换
    android中的byte数组转换(转)
    TensorFlow编译androiddemo
    Linux下命令行安装配置android sdk
    Warning: cast to/from pointer from/to integer of different size
    scribe 搭建遇到的问题
    参数依赖查找(ADL,Argument-dependent lookup)
    模板类继承后找不到父类函数的问题
  • 原文地址:https://www.cnblogs.com/ylwtsq/p/13356111.html
Copyright © 2011-2022 走看看