补题
codeforces 919D
题意
给定有向图\(G\),每个顶点上有不同的字母,求一条路径使得这条路径的经过的点的字母出现次数最大的次数最大,如果这个值可以任意大,输出\(-1\)
点数\(n \le 300000\)
解题思路
记dp[i][c]
表示以顶点\(i\)为终点的路径字母\(c\)出现的次数,那么考虑拓扑排序,在用\(kahn\)算法拓扑排序的过程中维护dp
值即可,如果图中存在环,那么这个值可以任意大,这点也可以通过拓扑排序来判断
AC代码
#include <bits/stdc++.h>
using namespace std;
const int maxn=300020;
int dp[maxn][28];
vector <int> G[maxn];
int deg[maxn];
char str[maxn];
int n,m;
bool topo_sort()
{
queue <int> Q;
for (int i=1;i<=n;i++)
if(!deg[i]) Q.push(i);
int cnt=0;
while(!Q.empty())
{
int u=Q.front();Q.pop();
cnt++;
dp[u][str[u-1]-‘a‘]++;
for (int v:G[u])
{
deg[v]--;
for (int i=0;i<=‘z‘-‘a‘;i++)
dp[v][i]=max(dp[u][i],dp[v][i]);
if(!deg[v]) Q.push(v);
}
}
return cnt==n;
}
int main()
{
scanf("%d%d",&n,&m);
scanf("%s",str);
for (int i=1;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
deg[v]++;
}
if(topo_sort())
{
int ans=-1;
for (int i=1;i<=n;i++)
for (int j=0;j<=‘z‘-‘a‘;j++)
ans=max(dp[i][j],ans);
printf("%d\n",ans);
}
else puts("-1");
}
codeforce 919E
题意
给定\(x,a,b,p\),求出有多少\(n \le x\), \(s.t. n \times a^n \equiv b\ (mod\ p)\)
其中\(2?\le?p \le 10^6?+?3, 1?\le a,?b?<?p, 1?\le x?\le 10^{12}\)
然后……我的数论太差了,待补