[20200721NOIP提高組模擬T1]矩陣
阿新 • • 發佈:2020-07-21
題目大意:
給你一個數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])$$
code:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<algorithm> #define R register #define next exnttttttttttttttttttttt #definedebug 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('\n'); }