HDU D Tree [点分治]
题意:找路径积$\mod 1e6+3 = k$的字典序最小点对
作为一个点分治蒟蒻,写这道题花了两节课....
显然只要开一个桶$c[i]$记录当前路径积为$i$的最小点
然后处理一个子树时一个个子树遍历更新答案再更新$c$就行了
最后再把$c$复原
可以用一个栈记下更改过的$c$,但貌似比在遍历一遍树更慢?
然后注意更新和复原$c[w[u]]$
好了回教室上数学课啦
#pragma comment(linker,"/STACK:102400000,102400000") #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int N=1e5+5,M=1e6+5,P=1e6+3,INF=1e9; inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } int n;ll k,w[N]; struct edge{ int v,ne; }e[N<<1]; int h[N],cnt; inline void ins(int u,int v){ cnt++; e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt; cnt++; e[cnt].v=u;e[cnt].ne=h[v];h[v]=cnt; } int inv[M]; void iniInv(){ inv[1]=1; for(int i=2;i<P;i++) inv[i]=(ll)(P-P/i)*inv[P%i]%P; } int size[N],f[N],vis[N],root,allSize; void dfsRt(int u,int fa){ size[u]=1;f[u]=0; for(int i=h[u];i;i=e[i].ne){ int v=e[i].v; if(vis[v]||v==fa) continue; dfsRt(v,u); size[u]+=size[v]; f[u]=max(f[u],size[v]); } f[u]=max(f[u],allSize-size[u]); if(f[u]<f[root]) root=u; } int c[M],ans[2]; int st[N],top; void dfsDee(int u,int fa,int now){ if(!c[now]) c[now]=u;//,st[++top]=now; else c[now]=min(c[now],u); for(int i=h[u];i;i=e[i].ne){ int v=e[i].v; if(!vis[v]&&v!=fa) dfsDee(v,u,now*w[v]%P); } } void dfsAns(int u,int fa,int now){ int x=c[k*inv[now]%P],y=u; if(x){ if(x>y) swap(x,y); if(x<ans[0]||(x==ans[0]&&y<ans[1])) ans[0]=x,ans[1]=y; } for(int i=h[u];i;i=e[i].ne){ int v=e[i].v; if(!vis[v]&&v!=fa) dfsAns(v,u,now*w[v]%P); } } void dfsRec(int u,int fa,int now){ c[now]=0; for(int i=h[u];i;i=e[i].ne){ int v=e[i].v; if(!vis[v]&&v!=fa) dfsRec(v,u,now*w[v]%P); } } void dfsSol(int u){ vis[u]=1; c[w[u]]=u; for(int i=h[u];i;i=e[i].ne){ int v=e[i].v; if(!vis[v]){ dfsAns(v,u,w[v]); dfsDee(v,u,w[u]*w[v]%P); } } //while(top) c[st[top]]=0,top--; for(int i=h[u];i;i=e[i].ne) if(!vis[e[i].v]) dfsRec(e[i].v,u,w[u]*w[e[i].v]%P); c[w[u]]=0; for(int i=h[u];i;i=e[i].ne){ int v=e[i].v; if(!vis[v]){ root=0;allSize=size[v]; dfsRt(v,0); dfsSol(root); } } } int main(){ freopen("in","r",stdin); iniInv(); while(scanf("%d%lld",&n,&k)!=EOF){ memset(vis,0,sizeof(vis)); cnt=0;memset(h,0,sizeof(h)); memset(c,0,sizeof(c)); for(int i=1;i<=n;i++) w[i]=read(); for(int i=1;i<=n-1;i++) ins(read(),read()); ans[0]=ans[1]=INF; f[0]=INF; root=0;allSize=n; dfsRt(1,0); dfsSol(root); if(ans[0]!=INF) printf("%d %d\n",ans[0],ans[1]); else puts("No solution"); } }
Copyright:http://www.cnblogs.com/candy99/