analysis
tarjan+DAG的DP
本题AC
code
#include<bits/stdc++.h>
using namespace std;
#define loop(i,start,end) for(register int i=start;i<=end;++i)
#define clean(arry,num) memset(arry,num,sizeof(arry))
#define anti_loop(i,start,end) for(register int i=start;i>=end;--i)
#define ll long long
template<typename T>void read(T &x){
x=0;char r=getchar();T neg=1;
while(r>'9'||r<'0'){if(r=='-')neg=-1;r=getchar();}
while(r>='0'&&r<='9'){x=(x<<1)+(x<<3)+r-'0';r=getchar();}
x*=neg;
}
int n;
const int maxn=100000+10;
struct node{
int e;
int nxt;
}edge[maxn];
int head[maxn];
int cnt=0;
inline void addl(int u,int v){
edge[cnt].e=v;
edge[cnt].nxt=head[u];
head[u]=cnt++;
}
int bel[maxn];
int sta[maxn];
int top=0;
int low[maxn];
int dfn[maxn];
int nfp=0;
int col=0;
int W[maxn];
int in[maxn];
void tarjan(int u){
sta[++top]=u;
low[u]=dfn[u]=++nfp;
for(int i=head[u];i!=-1;i=edge[i].nxt){
int v=edge[i].e;
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}else if(!bel[v]) low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u]){
bel[u]=++col;
++W[col];
while(sta[top]!=u){
bel[sta[top]]=col;
++W[col];
--top;
}
--top;
}
}
struct road{
int xi;
int yi;
}line[maxn];
inline bool cmp(road a,road b){
return ((a.xi==b.xi)?a.yi<b.yi:a.xi<b.xi);
}
void reset(){
loop(i,1,n)
line[i].xi=bel[line[i].xi],
line[i].yi=bel[line[i].yi];
sort(line+1,line+1+n,cmp);
clean(head,-1);
cnt=0;
loop(i,1,n){
if(line[i].xi!=line[i].yi&&(line[i].xi!=line[i-1].xi||line[i].yi!=line[i-1].yi)){
addl(line[i].xi,line[i].yi);
++in[line[i].yi];
}
}
}
int f[maxn];
void dfs(int u){
if(f[u])
return;
f[u]=W[u];
for(int i=head[u];i!=-1;i=edge[i].nxt){
int v=edge[i].e;
dfs(v);
f[u]+=f[v];
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("datain.txt","r",stdin);
#endif
read(n);
clean(head,-1);
loop(i,1,n){
int vi;
read(vi);
line[i].xi=i;
line[i].yi=vi;
addl(i,vi);
}
clean(bel,0);
clean(sta,0);
clean(low,0);
clean(dfn,0);
clean(W,0);
clean(in,0);
loop(i,1,n)
if(!dfn[i])
tarjan(i);
reset();
clean(f,0);
loop(i,1,col)
if(in[i]==0&&f[i]==0)
dfs(i);
//debug
loop(i,1,col)
if(!f[i]){
printf("ERROR\n");//实际上这行并不会输出
return 0;
}
//debug
loop(i,1,n)
printf("%d\n",f[bel[i]]);
return 0;
}