标签:
题意:
给你一棵树n个点,一个K
让你找到一条 a->b 的字典数最小的 路径满足 这条路径 上点权 乘积取mod下 等于K
题解:
预处理小于mod的 所有逆元
树分治 即可
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> #include<vector> #include<map> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define ls i<<1 #define rs ls | 1 #define mid ((ll+rr)>>1) #define pii pair<int,int> #define MP make_pair typedef long long LL; const long long INF = 1e18; const double Pi = acos(-1.0); const int N = 1e5+10, M = 1e6+11, inf = 2e9, mod = 1000003; int head[N],vis[N],f[N],siz[N],id[N],n,t = 1,ansl,ansr,allnode,root; struct edge{int to,next;}e[N * 4]; LL mp[M],inv[M],v[M],K,deep[M]; void add(int u,int v) {e[t].next=head[u];e[t].to=v;head[u]=t++;} void getroot(int u,int fa) { f[u] = 0; siz[u] = 1; for(int i = head[u]; i; i = e[i].next) { int to = e[i].to; if(vis[to] || to == fa) continue; getroot(to,u); siz[u] += siz[to]; f[u] = max(f[u],siz[to]); } f[u] = max(f[u], allnode - siz[u]); if(f[u] < f[root]) root = u; } void getdeep(int u,int fa,LL now) { deep[++deep[0]] = now*v[u]%mod; id[deep[0]] = u; for(int i = head[u]; i; i = e[i].next) { int to = e[i].to; if(vis[to] || to == fa) continue; getdeep(to,u,now*v[u]%mod); } } void update(int u,int x,int y) { int tmp = mp[inv[x*v[u]%mod]*K%mod]; if(!tmp) return ; if(y > tmp) swap(y,tmp); if(y < ansl || (y == ansl && tmp < ansr)) ansl = y, ansr = tmp; } void work(int u){ vis[u] = 1; mp[1] = u; for(int i = head[u]; i; i = e[i].next) { int to = e[i].to; if(vis[to]) continue; deep[0] = 0; getdeep(to,u,1); for(int j = 1; j <= deep[0]; ++j) update(u,deep[j],id[j]); for(int j = 1; j <= deep[0]; ++j) if(!mp[deep[j]] || mp[deep[j]] > id[j])mp[deep[j]] = id[j]; } mp[1] = 0; for(int i = head[u]; i; i = e[i].next) { int to = e[i].to; if(vis[to]) continue; deep[0] = 0; getdeep(to,u,1); for(int j = 1; j <= deep[0]; ++j) mp[deep[j]] = 0; } for(int i = head[u]; i; i = e[i].next) { int to = e[i].to; if(vis[to]) continue; root = 0; allnode = siz[to]; getroot(e[i].to,root); work(root); } } int main() { inv[1]=1; for(int i=2;i<mod;i++){int a=mod/i,b=mod%i;inv[i]=(inv[b]*(-a)%mod+mod)%mod;} while(~scanf("%d%I64d",&n,&K)) { t = 1;memset(head,0,sizeof(head)); memset(vis,0,sizeof(vis)); ansl = ansr = inf; for(int i = 1; i <= n; ++i) scanf("%I64d",&v[i]); for(int i = 1; i < n; ++i) { int u,v; scanf("%d%d",&u,&v); add(u,v); add(v,u); } f[0]=inf; allnode=n;root=0; getroot(1,0); work(root); if(ansl == inf) puts("No solution");else printf("%d %d\n",ansl,ansr); } return 0; }
标签:
原文地址:http://www.cnblogs.com/zxhl/p/5772519.html