食物链
题目描述:(暂不提供)
这道题考场就想出来了。
很明显这是一道 上跑 的题目,想到拓扑。
然后突然就脑抽了一下,忘记了拓扑。
不过还好,也就是推了一分钟就把拓扑和 推出来了。
这道题主要不是考你思路,主要是看你如何处理那些稀奇古怪的名字。
考场
选了
,然后有一个点被卡了。
以为自己
要垫底了,结果没想到写双哈希的人都被卡了,自己只被卡了一个点,竟然
单题第一。
考后请教 换了双哈希然后就过了。
%:pragma GCC optimize(2)
%:pragma GCC optimize("Ofast")
%:pragma GCC optimize("inline")
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
typedef long long ll;
const int N = 500010;
const int P = 131;
const int mo = 1000000007;
const int mod = 998244353;
const int Mod = 1000000007;
map<pair<int, int>, int> vis;
struct Edge{ int to,nxt; } g[N << 1];
int last[N],cnt = 0,len;
int n,tot = 0,r,stk[N],st[N],l;
ll ret = 0,f[N],d[N],ans,bz[N],ret1 = 0;
char s[80];
void add(int u,int v) { g[++cnt] = (Edge){ v,last[u] }, last[u] = cnt; }
int main()
{
freopen("chain.in","r",stdin);
freopen("chain.out","w",stdout);
scanf("%d",&n);
for(int i = 1,x,y;i <= n; ++ i)
{
pair<int, int> tmp = make_pair(0,0);
scanf(" %s",s + 1); len = strlen(s + 1); ret = 0, ret1 = 0;
for(int j = 1;j <= len; ++ j)
if(s[j] >= 'A' && s[j] <= 'Z') { ret = (1ll * ret * P % mod + (s[j] - 'A' + 1)) % mod, ret1 = (1ll * ret1 * P % mo + (s[j] - 'A' + 1)) % mo; }
else { ret = (1ll * ret * P % mod + (s[j] - 'a' + 27)) % mod, ret1 = (1ll * ret1 * P % mo + (s[j] - 'a' + 27)) % mo; }
tmp = make_pair((int)ret,(int)ret1);
if(!vis[tmp]) vis[tmp] = x = ++tot; else x = vis[tmp];
scanf(" %s",s + 1); len = strlen(s + 1); ret = 0, ret1 = 0;
for(int j = 1;j <= len; ++ j)
if(s[j] >= 'A' && s[j] <= 'Z') { ret = (1ll * ret * P % mod + (s[j] - 'A' + 1)) % mod, ret1 = (1ll * ret1 * P % mo + (s[j] - 'A' + 1)) % mo; }
else { ret = (1ll * ret * P % mod + (s[j] - 'a' + 27)) % mod, ret1 = (1ll * ret1 * P % mo + (s[j] - 'a' + 27)) % mo; }
tmp = make_pair((int)ret,(int)ret1);
if(!vis[tmp]) vis[tmp] = y = ++tot; else y = vis[tmp];
if(x == y) continue;
add(x,y); ++d[y]; bz[x] = 1;
}
ret = 0; l = 1;
for(int i = 1;i <= tot; ++ i) if(!d[i]) stk[++r] = i,f[i] = 1,ret = (ret + f[i]) % Mod; ans = ret;
ret = 0;
for(;l <= r; ++l)
for(int i = last[stk[l]];i;i = g[i].nxt)
{
--d[g[i].to], f[g[i].to] = (f[g[i].to] + f[stk[l]]) % Mod;
if(!d[g[i].to]) stk[++r] = g[i].to;
if(!bz[g[i].to] && !d[g[i].to]) ret = (ret + f[g[i].to]) % Mod;
}
if(ret) ans = ret;
printf("%lld",ans);
fclose(stdin); fclose(stdout);
return 0;
}