B:2018-div-matrix
题意:
Bobo 想统计满足下面条件的矩阵 A 的数量。
1. 矩阵 A 有 n 行 m 列,每个元素都是正整数。第 i 行第 j 列的元素用Aij 表示。
2. A1,1 = 2018
3. 对于所有的2<=i<=n,1<=j<=m,Ai,j是Ai-1,j的约数
4. 对于所有的1<=i<=n,2<=j<=m,Ai,j是Ai,j-1的约数
因为满足条件的矩阵 A 数量很多,Bobo 只想统计满足条件的矩阵数量除以(10^9+7)的余数
题解:
听说这是catalan数,百度一下这是个排列组合的数,反正打表就出来了
结果是(C(n+m,n)-1)×(C(n+m,m)-1)
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod = 1e9+7;
const int maxx = 4010;
ll pow_mod(ll a,ll b)
{
ll ans = 1;
while(b){
if(b&1)
ans = ans*a%mod;
a = a*a%mod;
b>>=1;
}
return ans;
}
ll a[maxx],b[maxx];
void solve()
{
a[0] = 1;
for(ll i=1;i<=4005;i++){
a[i] = (a[i-1]*i)%mod;
b[i] = pow_mod(a[i],mod-2);
}
}
ll C(ll x,ll y)
{
return a[x]*b[y]%mod*b[x-y]%mod;
}
int main()
{
solve();
int n,m;
while(~scanf("%d%d",&n,&m))
{
printf("%lld\n",(C(n+m,n)-1)*(C(n+m,m)-1)%mod );
}
return 0;
}
J:买一送一
题意:
给出一个有向图,可以说是一棵树,每个节点相当于一个商店,每个商店有一个商品的类型,Bobo 从商店 1 出发前往商店 i。他要在两个不同的商店购买商品(包括商店 1 和 i)。设他先购买的商品类型是 x,后购买的商品类型是 y,他用 fi表示不同的有序对<x,y> 的数量。问你f2,f3....fn
题解:
深搜,当前节点的fi = 前一个节点的fi + 以当前节点为第二个商品的有序对的个数 - 之前以当前节点为第二个商品的有序对的个数
#include <bits/stdc++.h>
using namespace std;
#define ll unsigned long long
const int maxx = 100005;
vector<int> v[maxx];
int b[maxx],sign[maxx];
ll f[maxx],pre[maxx];
int cnt = 0;
void dfs(int x)
{
for(int i=0;i<v[x].size();i++)
{
int k = v[x][i];
f[k] = f[x] + cnt - pre[b[k]];//gengxin
int now = pre[b[k]];
pre[b[k]] = cnt;
int flag = 0;
if(!sign[b[k]]){
cnt++,flag = 1;
}
sign[b[k]]++;
dfs(k);
pre[b[k]] = now;
if(flag)
cnt--;
sign[b[k]]--;
}
}
int main()
{
int n,x;
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++) {
v[i].clear();
f[i] = 0,pre[i] = 0,sign[i] = 0;
}
for(int i=2;i<=n;i++){
scanf("%d",&x);
v[x].push_back(i);
}
for(int i=1;i<=n;i++){
scanf("%d",&b[i]);
}
cnt = 1,sign[b[1]] = 1;
dfs(1);
for(int i=2;i<=n;i++){
printf("%lld\n",f[i]);
}
}
return 0;
}
K:Use FFT
题意:
给出俩个多项式P(x)=a0 + a1x + … + anx^n 和 Q(x)=b0 + b1x + … + bmx^m.
P(x)⋅Q(x)=c0 + c1x + … + cn+mx^(n+m),输出(cL + c(L+1) + … + cR) modulo(10^9 + 7)for given L and R.
题解:
先求出bi的前缀和,循环一遍min(r,n),每次前缀和--
#include <bits/stdc++.h>
using namespace std;
#define ll unsigned long long
const int maxx = 1000005;
ll a[maxx],b[maxx],pre[maxx*2];
const ll mod = 1e9+7;
int main()
{
ll n,m,l,r;
while(~scanf("%lld%lld%lld%lld",&n,&m,&l,&r))
{
for(int i=0;i<=n;i++)
scanf("%lld",&a[i]);
for(int i=0;i<=m;i++){
scanf("%lld",&b[i]);
if(i == 0)
pre[i] = b[i];
else{
pre[i] = pre[i-1] + b[i];
}
pre[i] %= mod;
}
ll ans = 0;
for(int i=m+1;i<=r;i++)
pre[i] = pre[i-1];
for(int i=0;i<=min(r,n);i++){
if(l-i-1 >=0)
ans += a[i]*((pre[r-i]-pre[l-i-1]+mod)%mod);
else
ans += a[i]*pre[r-i];
//cout<<ans<<endl;
ans %= mod;
}
printf("%lld\n",ans);
}
return 0;
}