2023.5.18测试
T1 金币
(其实是原题 P3951 [NOIP2017 提高组] 小凯的疑惑)
给定
考场上想了很久,幸好搞出来了
因为
但现在
考虑让
综上,答案为
T2 字符串计数
一个长度为
考场上脑瘫把组合写成排列了,一直搞不出来,最后喜提
设大写字母、小写字母,数字的数量依次为
考虑
现在思考如何优化。观察到大小写字母的底数都是
考虑如何计算
设
可
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int N=200010;
const LL MOD=1e9+9;
int len,a,b,c;
LL fac[N],f[N],g[N],ans;
LL ksm(LL x,LL y)
{
if(y==0)
return 1;
if(y==1)
return x;
LL tmp=ksm(x,y/2);
if(y&1)
return tmp*tmp%MOD*x%MOD;
return tmp*tmp%MOD;
}
LL C(int a,int b)
{
if(a<b || a<0 || b<0)
return 0;
if(b==0)
return 1;
if(a==0)
return 0;
return fac[a]*ksm(fac[a-b],MOD-2)%MOD*ksm(fac[b],MOD-2)%MOD;
}
int main()
{
fac[0]=1;
for(int i=1; i<=2e5+1; i++)
fac[i]=(fac[i-1]*i)%MOD;
scanf("%d%d%d%d",&len,&a,&b,&c);
if(a+b+c>len)
{
printf("0");
return 0;
}
for(int i=a+b; i<=len-c; i++)
{
if(i==a+b) //注意这地方当a+b=0时就不好递推了,所以边界自己处理
g[i]=C(i,a);
else
g[i]=(g[i-1]*2%MOD+C(i-1,a-1)+C(i-1,i-b))%MOD;
f[i]=ksm(26,i)*g[i]%MOD;
(ans+=f[i]*ksm(10,len-i)%MOD*C(len,len-i)%MOD)%=MOD;
}
printf("%lld",ans);
return 0;
}
T3 树
一棵带边权的树,边权为
一眼点分治。考场上迅速码完,calc
函数直接两重循环暴力判断。由于数据太弱,喜提
不过还是要思考如何优化
对于
利用
把
对于
预处理出
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int N=100010,M=5000010;
struct node
{
LL sa,sb; //sa倒着,sb正着
int cnt;
}a[N];
int n,p,L;
int rt,rt_size,size[N];
int head[N],nxt[2*N],ver[2*N],edge[2*N],tot;
bool v[N];
LL m,inv[N],ans;
map <LL,int> aa,bb;
LL exgcd(LL a,LL b,LL &x,LL &y)
{
if(b==0)
{
x=1; y=0;
return a;
}
LL d=exgcd(b,a%b,x,y);
LL tmp=x;
x=y; y=tmp-(a/b)*y;
return d;
}
void add(int x,int y,int z)
{
ver[++tot]=y; edge[tot]=z;
nxt[tot]=head[x]; head[x]=tot;
}
void find_root(int x,int fa,int Large)
{
int max_part=0;
size[x]=1;
for(int i=head[x]; i; i=nxt[i])
{
int y=ver[i];
if(y==fa || v[y])
continue;
find_root(y,x,Large);
size[x]+=size[y];
max_part=max(max_part,size[y]);
}
max_part=max(max_part,Large-size[x]);
if(max_part<rt_size)
{
rt=x;
rt_size=max_part;
}
}
void dfs(int x,int fa,LL numa,LL numb,LL pw,int t)
{
a[++p]=(node){numa,numb*inv[t]%m,t};
for(int i=head[x]; i; i=nxt[i])
{
int y=ver[i],z=edge[i];
if(y==fa || v[y])
continue;
LL nta=(1LL*z*pw+numa)%m;
LL ntb=(numb*10%m+(LL)z)%m;
dfs(y,x,nta,ntb,pw*10%m,t+1);
}
}
void calc()
{
for(int i=1; i<=p; i++)
{
ans+=(LL)bb[(m-a[i].sa)%m];
ans+=(LL)aa[(m-a[i].sb)%m];
}
for(int i=1; i<=p; i++)
{
aa[a[i].sa]++;
bb[a[i].sb]++;
}
p=0;
}
void solve(int x,int fa,int Large)
{
rt_size=Large+1;
find_root(x,fa,Large);
v[rt]=1;
p=0;
aa[0]++; bb[0]++;
for(int i=head[rt]; i; i=nxt[i])
{
int y=ver[i],z=edge[i];
if(y==fa || v[y])
continue;
dfs(y,rt,(LL)z%m,(LL)z%m,10,1);
calc();
}
aa.clear(); bb.clear();
for(int i=head[rt]; i; i=nxt[i])
{
int y=ver[i];
if(y==fa || v[y])
continue;
solve(y,x,size[y]);
}
}
int main()
{
scanf("%d%lld",&n,&m);
for(int i=1; i<n; i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
x++; y++;
add(x,y,z); add(y,x,z);
}
LL pw=1;
for(int i=1; i<=n; i++)
{
(pw*=10)%=m;
LL x,y;
exgcd(pw,m,x,y);
x=(x%m+m)%m;
inv[i]=x;
}
solve(1,0,n);
printf("%lld",ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?