fateice来到了膜方俱乐部旅行。膜方俱乐部有N个分部,每个分部均有且仅有一个虫洞,但是这虫洞只能通往一个分部。每个分部有一个orzFang价值,第 i 个分部的orzFang价值为A[i]。
现在他想知道,从i个分部出发,并只通过虫洞前往下一个分部,orzFang价值之和最多是多少(到达一个分部多次只计算 1 次orzFang价值)。
做了好几次了,每次都是写递归80tps。。这次补下100分的循环写法。
const int N = 2e5 + 79;
int a[N], to[N];
int n;
int v[N], in[N], ans[N],q[N];
int main() {
freopen("travel.in","r",stdin);
freopen("travel.out","w",stdout);
read(n);
rep(i, 1, n) {
read(a[i]);
}
rep(i, 1, n) {
read(to[i]);
++in[to[i]];
}
rep(i,1,n){
if(!in[i]) q[++q[0]]=i;
}
rep(kkk,1,q[0]){
int x=q[kkk];
v[x]=1;
if(!--in[to[x]]) q[++q[0]]=to[x];
}
rep(i,1,n){
if(!v[i]){
int st(i),sum(a[i]);
int x(i);
v[x]=1;
while(to[x]!=st){
x=to[x];
v[x]=1;
sum+=a[x];
}
x=i;
ans[x]=sum;
while(to[x]!=st){
x=to[x];
ans[x]=sum;
}
}
}
drp(i,q[0],1){
ans[q[i]]=a[q[i]]+ans[to[q[i]]];
}
rep(i, 1, n) out(ans[i], '
');
return 0;
}
MLE
const int N = 2e5 + 79;
int a[N], to[N];
int n;
int vis[N], in[N], ans[N];
inline void dfs(int x) {
vis[x] = 1;
if(!(--in[to[x]]))dfs(to[x]);
}
inline int calccircle(int x, int tot) {
ans[x] = tot;
if(ans[to[x]]) return tot;
else return ans[x] = calccircle(to[x], tot + a[to[x]]);
}
inline int calc(int x) {
if(ans[x]) return ans[x];
else return ans[x] = calc(to[x]) +a[x];
}
int main() {
freopen("travel.in","r",stdin);
freopen("travel.out","w",stdout);
read(n);
rep(i, 1, n) {
read(a[i]);
}
rep(i, 1, n) {
read(to[i]);
++in[to[i]];
}
rep(i, 1, n) {
if(!in[i] && !vis[i]) dfs(i);
}
rep(i, 1, n) {
if(in[i] && !ans[i]) calccircle(i, a[i]);
}
rep(i, 1, n) {
if(!in[i] && !ans[i]) calc(i);
}
rep(i, 1, n) out(ans[i], '
');
return 0;
}