5 60 2 5 2 3 3 1 2 1 3 2 4 2 5 5 2 2 5 2 3 3 1 2 1 3 2 4 2 5
3 4 No solutionHint1. “please print the lexicographically smallest one.”是指: 先按照第一个数字的大小进行比较,若第一个数字大小相同,则按照第二个数字大小进行比较,依次类推。 2. 若出现栈溢出,推荐使用C++语言提交,并通过以下方式扩栈: #pragma comment(linker,"/STACK:102400000,102400000")
#include<algorithm> #include<iostream> #include<string.h> #include<stdio.h> #pragma comment(linker,"/STACK:102400000,102400000") using namespace std; const int INF=0x3f3f3f3f; const int maxn=100010; const int mod=1e6+3; typedef long long ll; ll inv[mod+10]; int val[maxn],ms[maxn],son[maxn],vis[maxn],cnt,kv; int mp[mod+10],use[mod+10],ptr,pos,ans1,ans2; struct node { int v; node *next; } ed[maxn<<1],*head[maxn]; void adde(int u,int v) { ed[cnt].v=v; ed[cnt].next=head[u]; head[u]=&ed[cnt++]; } void dfs(int fa,int u) { son[u]=1; ms[u]=0; for(node *p=head[u];p!=NULL;p=p->next) { if(p->v==fa||vis[p->v]) continue; dfs(u,p->v); son[u]+=son[p->v]; ms[u]=max(ms[u],son[p->v]); } } void findroot(int fa,int u,int all) { ms[u]=max(ms[u],all-son[u]); if(ms[u]<ms[pos]) pos=u; for(node *p=head[u];p!=NULL;p=p->next) { if(p->v==fa||vis[p->v]) continue; findroot(u,p->v,all); } } void getroot(int u) { dfs(-1,u); pos=u; findroot(-1,u,son[u]); } void cal(int fa,int u,int mc)//计算答案 { mc=(ll)mc*val[u]%mod; int op=(ll)kv*inv[mc]%mod,a,b; if(mp[op]) { a=u,b=mp[op]; if(a>b) swap(a,b); if(a<ans1) ans1=a,ans2=b; else if(a==ans1&&b<ans2) ans2=b; } for(node *p=head[u];p!=NULL;p=p->next) { if(p->v==fa||vis[p->v]) continue; cal(u,p->v,mc); } } void update(int fa,int u,int mc)//更新hash表 { mc=(ll)mc*val[u]%mod; if(!mp[mc]) use[ptr++]=mc,mp[mc]=u; else mp[mc]=min(mp[mc],u); for(node *p=head[u];p!=NULL;p=p->next) { if(p->v==fa||vis[p->v]) continue; update(u,p->v,mc); } } void solve(int u)//每次处理一颗子树 { int root,i; getroot(u); root=pos; mp[val[root]]=root; vis[root]=1,ptr=0; for(node *p=head[root];p!=NULL;p=p->next) { if(vis[p->v]) continue; cal(root,p->v,1);//计算子树路径 update(root,p->v,val[root]); } for(i=0;i<ptr;i++) mp[use[i]]=0; mp[val[root]]=0; for(node *p=head[root];p!=NULL;p=p->next) { if(vis[p->v]) continue; solve(p->v); } } int main() { int n,i,u,v; inv[1]=1; for(i=2;i<mod;i++)//预处理逆元 inv[i]=(mod-mod/i)*inv[mod%i]%mod; while(~scanf("%d%d",&n,&kv)) { for(i=1;i<=n;i++) scanf("%d",&val[i]); memset(head,0,sizeof head); memset(vis,0,sizeof vis); cnt=0; for(i=1;i<n;i++) { scanf("%d%d",&u,&v); adde(u,v); adde(v,u); } ans1=ans2=INF; solve(1); if(ans1!=INF) printf("%d %d\n",ans1,ans2); else printf("No solution\n"); } return 0; }
原文地址:http://blog.csdn.net/bossup/article/details/40262755