倍增T成75求助
  • 板块P5557 旅行
  • 楼主Lates
  • 当前回复0
  • 已保存回复0
  • 发布时间2020/11/20 22:04
  • 上次更新2023/11/5 07:38:55
查看原帖
倍增T成75求助
119062
Lates楼主2020/11/20 22:04

没写倍增还有 80 (

75 pts:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm> 
using namespace std;
#define int long long 
inline int read(){
	register int x=0,f=0,ch=getchar();
	while('0'>ch||ch>'9')f^=ch=='-',ch=getchar();
	while('0'<=ch&&ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=getchar();
	return f?-x:x;
}
const int MAX=5e5;
int T,n,mod,s,t,l;
int to[MAX],vis[MAX];
int de[MAX],dis[MAX];
int sccc[MAX],sc[MAX],scc,siz[MAX],dfn[MAX],st[MAX],top,low[MAX],tim;
void tarjan(int x){
	low[x]=dfn[x]=++tim;
	st[++top]=x;
	if(!dfn[to[x]])tarjan(to[x]),low[x]=min(low[x],low[to[x]]);
	else if(!sc[to[x]])low[x]=min(low[x],dfn[to[x]]);
	if(low[x]==dfn[x]){
		++scc;
		while(x!=st[top+1]){sc[st[top]]=scc;++siz[scc],--top;}
	}
}
void dfs(int x,int tot){
	if(siz[sc[x]]>1||to[x]==x){
		dis[x]=0;
		sccc[x]=sc[x];
		return ;
	}
	dfs(to[x],tot+1);
	dis[x]=dis[to[x]]+1;
	sccc[x]=sccc[to[x]];
}
int check(int x,int l,int p){
	if(x==1)return 0;
	for(register int i=0,res=1;i<=l;++i){
		if(res>p)return 1;
		res*=x;
	}
	return 0;
}
inline int qpow(int x,int p,int P){
	register int res=1;
	for(;p;p>>=1,x=1ll*x*x%P)if(p&1)res=1ll*res*x%P;
	return res;
}
int f[MAX][40];
inline int solve(int x,int s){
	for(register int i=31;i>=0;--i)if(x>>i&1)s=to[f[s][i]];
	return s;
}
signed main(){
//	freopen("in.in","r",stdin);
//	freopen("out.out","w",stdout);
	n=read();
	for(register int i=1,u;i<=n;++i)u=read(),to[i]=u,++de[u],f[i][0]=i;
	for(register int i=1;i<=n;++i)if(!dfn[i])tarjan(i);
	for(register int i=1;i<=n;++i)if(siz[sc[i]]==1&&to[i]!=i&&!de[i])dfs(i,1);
	for(register int i=1;i<=n;++i)if(siz[sc[i]]>1||to[i]==i)sccc[i]=0;
	
	for(register int j=1;j<=31;++j){
		for(register int i=1;i<=n;++i){
			f[i][j]=f[to[f[i][j-1]]][j-1];
		}
	}
	T=read(); 
	while(T--){
		s=read(),t=read(),l=read();
		if(check(t,l,dis[s])){//t^l>dis[s] 
			if(siz[sc[s]]>1){
				t=qpow(t,l,siz[sc[s]]);
			}else if(to[s]==s){
				t=1;
			}else{
				mod=siz[sccc[s]];
				t=qpow(t,l,mod);
				t=(t-dis[s])%mod;t=(t+mod)%mod; 
				t+=dis[s];				
			}
			s=solve(t,s);
		}else{
			t=qpow(t,l,0x7fffffff);
			s=solve(t,s);
		}
		printf("%lld\n",s); 
	}
	return 0;
}

80:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm> 
using namespace std;
#define int long long 
inline int read(){
	register int x=0,f=0,ch=getchar();
	while('0'>ch||ch>'9')f^=ch=='-',ch=getchar();
	while('0'<=ch&&ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=getchar();
	return f?-x:x;
}
const int MAX=5e5;
int T,n,mod,s,t,l;
int to[MAX],vis[MAX];
int de[MAX],dis[MAX];
int sccc[MAX],sc[MAX],scc,siz[MAX],dfn[MAX],st[MAX],top,low[MAX],tim;
void tarjan(int x){
	low[x]=dfn[x]=++tim;
	st[++top]=x;
	if(!dfn[to[x]])tarjan(to[x]),low[x]=min(low[x],low[to[x]]);
	else if(!sc[to[x]])low[x]=min(low[x],dfn[to[x]]);
	if(low[x]==dfn[x]){
		++scc;
		while(x!=st[top+1]){sc[st[top]]=scc;++siz[scc],--top;}
	}
}
void dfs(int x,int tot){
	if(siz[sc[x]]>1||to[x]==x){
		dis[x]=0;
		sccc[x]=sc[x];
		return ;
	}
	dfs(to[x],tot+1);
	dis[x]=dis[to[x]]+1;
	sccc[x]=sccc[to[x]];
}
int check(int x,int l,int p){
	if(x==1)return 0;
	for(register int i=0,res=1;i<=l;++i){
		if(res>p)return 1;
		res*=x;
	}
	return 0;
}
inline int qpow(int x,int p,int P){
	register int res=1;
	for(;p;p>>=1,x=1ll*x*x%P)if(p&1)res=1ll*res*x%P;
	return res;
}
signed main(){
//	freopen("in.in","r",stdin);
//	freopen("out.out","w",stdout);
	n=read();
	for(register int i=1,u;i<=n;++i)u=read(),to[i]=u,++de[u];
	for(register int i=1;i<=n;++i)if(!dfn[i])tarjan(i);
	for(register int i=1;i<=n;++i)if(siz[sc[i]]==1&&to[i]!=i&&!de[i])dfs(i,1);
	for(register int i=1;i<=n;++i)if(siz[sc[i]]>1||to[i]==i)sccc[i]=0;
	T=read(); 
	while(T--){
		s=read(),t=read(),l=read();
		if(check(t,l,dis[s])){//t^l>dis[s] 
			if(siz[sc[s]]>1){
				t=qpow(t,l,siz[sc[s]]);
			}else if(to[s]==s){
				t=1;
			}else{
				mod=siz[sccc[s]];
				t=qpow(t,l,mod);
				t=(t-dis[s])%mod;t=(t+mod)%mod; 
				t+=dis[s];				
			}

			while(t--)s=to[s]; 
		}else{
			t=qpow(t,l,0x7fffffff);
			while(t--)s=to[s];
		}
		printf("%lld\n",s); 
	}
	return 0;
}
2020/11/20 22:04
加载中...