标签:
1 HDU4812(树分治
题目:求一颗树上的一条路径,其上所有点的值之积为k。
思路:裸的树分治,写的时候感觉肯定能迅速过掉,,,,结果做了大半天。。。越来越觉得自己出数据的能力是极为重要的!!!
/* * @author: Cwind */ ///#pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <map> #include <algorithm> #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #include <queue> #include <stack> #include <functional> #include <set> #include <cmath> using namespace std; #define IOS std::ios::sync_with_stdio (false);std::cin.tie(0) #define pb push_back #define PB pop_back #define bk back() #define fs first #define se second #define sq(x) (x)*(x) #define eps (1e-6) #define IINF (1<<29) #define LINF (1ll<<59) #define INF (1000000000) #define FINF (1e3) #define clr(x) memset((x),0,sizeof (x)); typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; typedef pair<ll,ll> P; const int maxn=1e5+3000; const ll mod=1e6+3; int n,k; int val[maxn]; vector<int> G[maxn]; int cnt; bool usd[maxn]; int inv[mod]; int qpow(ll a,ll p){ ll ans=1; while(p){ if(p&1) ans=(ans*a)%mod; p>>=1; a=(a*a)%mod; } return ans; } void count(int v,int f=-1){ cnt++; for(int i=0;i<G[v].size();i++){ int u=G[v][i]; if(usd[u]||u==f) continue; count(u,v); } } int center,mind; int snum[maxn]; void getCenter(int v,int f=-1){ int maxs=0; snum[v]=0; for(int i=0;i<G[v].size();i++){ int u=G[v][i]; if(usd[u]||u==f) continue; getCenter(u,v); maxs=max(maxs,snum[u]+1); snum[v]+=snum[u]+1; } int val=max(cnt-snum[v]-1,maxs); if(val<mind){ mind=val; center=v; } } int tab[mod],chd[mod],ch; int tmptab[mod],chtmp[mod],tch; P ans; void cal_tab(int v,ll mul=1,int f=-1){ ll m=mul*val[v]%mod; if(!tmptab[m]){ chtmp[tch++]=m; tmptab[m]=v; }else{ if(tmptab[m]>v) tmptab[m]=v; } for(int i=0;i<G[v].size();i++){ int u=G[v][i]; if(u==f||usd[u]) continue; cal_tab(u,m,v); } } void solve(int v){ usd[v]=1; ll dv=inv[val[v]]; for(int i=0;i<G[v].size();i++){ int u=G[v][i]; if(usd[u]) continue; cal_tab(u); for(int j=0;j<tch;j++){ int tv=chtmp[j]; int tar=inv[tv]*dv%mod*k%mod; if((ll)val[v]*tv%mod==k){ int a=v,b=tmptab[tv]; if(a>b) swap(a,b); ans=min(ans,P(a,b)); } if(tab[tar]){ int a=tab[tar],b=tmptab[tv]; if(a>b) swap(a,b); ans=min(ans,P(a,b)); } } for(int j=0;j<tch;j++){ int tv=chtmp[j]; if(tab[tv]){if(tmptab[tv]<tab[tv]) tab[tv]=tmptab[tv];} else{ tab[tv]=tmptab[tv]; chd[ch++]=tv; } tmptab[tv]=0; } tch=0; } for(int i=0;i<ch;i++){ tab[chd[i]]=0; } ch=0; for(int i=0;i<G[v].size();i++){ int u=G[v][i]; if(usd[u]) continue; mind=1e9; cnt=0; count(u); getCenter(u); solve(center); } } void pre_cal(){ for(int i=0;i<mod;i++){ inv[i]=qpow(i,mod-2); } } void init(){ for(int i=0;i<=n;i++){ G[i].clear(); } ans=P(INF,INF); memset(usd,0,sizeof usd); } int main(){ freopen("/home/slyfc/CppFiles/in","r",stdin); pre_cal(); while(cin>>n>>k){ init(); for(int i=1;i<=n;i++){ scanf("%d",&val[i]); } for(int i=0;i<n-1;i++){ int x,y; scanf("%d%d",&x,&y); G[x].pb(y); G[y].pb(x); } mind=1e9,cnt=0; count(1);getCenter(1); solve(center); if(ans==P(INF,INF)){ puts("No solution"); }else{ printf("%d %d\n",(int)ans.fs,(int)ans.se); } } return 0; }
标签:
原文地址:http://www.cnblogs.com/Cw-trip/p/4857427.html