D - Decimal
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6;
int main()
{
int n,t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
if(maxn%n==0)
printf("No
");
else
printf("Yes
");
}
return 0;
}
F - Forest Program
题意:
给出一个 (n) 个点,(m) 条边的图,图中不包含自环,重边,并且一条边最多只出现在一个环中。求出去掉一些边后,图中剩余部分全部是树的方案数,模 (998244353)。
分析:
根据 (1) 条边最多出现在一个环中,用 (dfs) 来找环,并且求出每个环的边数。然后,用组合数学,二项式定理求解。
代码:
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
typedef pair<int,int>P;
typedef long long ll;
const int N=3e5+5;
const int mod=998244353;
vector<int>pic[N];
int dis[N],cir[N];
int cnt,n,m;
void dfs(int v,int p,int d)
{
if(dis[v]>-1)
{
if(d<=dis[v]) return;
cir[++cnt]=d-dis[v];
return;
}
dis[v]=d;
for(int i=0;i<pic[v].size();i++)
{
int u=pic[v][i];
if(u==p) continue;
dfs(u,v,d+1);
}
}
ll power(ll a,ll b)
{
ll res=1;
while(b)
{
if(b&1) res=res*a%mod;
b>>=1;
a=a*a%mod;
}
return res%mod;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
cnt=0;
int u,v;
for(int i=1;i<=n;i++)
{
pic[i].clear();
dis[i]=-1;
}
for(int i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
pic[u].pb(v);
pic[v].pb(u);
}
dfs(1,0,0);
int t=0;
ll ans=1;
for(int i=1;i<=cnt;i++)
t+=cir[i];
t=m-t;
for(int i=1;i<=cnt;i++)
ans=(ans*(power(2LL,1LL*cir[i])-1LL))%mod;
ans=ans*power(2LL,t)%mod;
printf("%lld
",(ans+mod)%mod);
}
return 0;
}
I - Invoker
线性DP。
https://www.cnblogs.com/1024-xzx/p/12991711.html
J - MUV LUV EXTRA
英文题目没看懂。
中文题面:http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1010&cid=872
把字符串反向,KMP最小循环节,枚举遍历取最优。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e7+5;
const int inf=0x3f3f3f3f;
int a,b;
char ss[N];
int nxt[N];
void getnxt(int len)
{
int k=-1,j=0;
nxt[0]=-1;
while(j<len)
{
if(k==-1||ss[j]==ss[k]) nxt[++j]=++k;
else k=nxt[k];
}
}
int main()
{
while(scanf("%d%d",&a,&b)!=EOF)
{
scanf("%s",ss);
int len=strlen(ss),p=1;
for(int i=0;i<len;i++)
{
if(ss[i]=='.')
{
p=i+1;
break;
}
}
for(int i=p;i<len;i++)
ss[i-p]=ss[i];
len=len-p;
ss[len]=' ';
for(int i=0;i<len/2;i++)
{
char t=ss[len-i-1];
ss[len-i-1]=ss[i];
ss[i]=t;
}
getnxt(len);
ll ans=-inf;//取足够小
for(int i=1;i<=len;i++)
{
ll t=1LL*a*i-1LL*b*(i-nxt[i]);
ans=max(ans,t);
}
printf("%lld
",ans);
}
return 0;
}
A - Angle Beats
计算几何。