HDU 4812 D Tree (樹上點分治),hdu4812

來源:互聯網
上載者:User

HDU 4812 D Tree (樹上點分治),hdu4812

題目地址:HDU 4812
這題是13年南京地區賽的現場題。
樹分治思想。
樹分治的過程中記錄下每個子樹的所有到達根的路徑的積,用best記錄下每個積的最小端點,然後再枚舉當前子樹的每個積,然後用逆元的方法求出當積為k時所需要的另一個端點值,並更新答案。
代碼如下:

#include <iostream>#include <string.h>#include <math.h>#include <queue>#include <algorithm>#include <stdlib.h>#include <map>#include <set>#include <stdio.h>#include <time.h>using namespace std;#define LL __int64#define pi acos(-1.0)#pragma comment(linker, "/STACK:1024000000")const int mod=1e6+3;const int INF=0x3f3f3f3f;const double eqs=1e-9;const int MAXN=100000+10;int head[MAXN], cnt, root, min1, ans1, ans2, tot, k, ff;int siz[MAXN], vis[MAXN], best[MAXN*10], flag[MAXN*10];LL Inv[MAXN*10], a[MAXN];struct N{        LL x;        int num;}F[MAXN];struct node{        int v, next;}edge[MAXN<<1];void add(int u, int v){        edge[cnt].v=v;        edge[cnt].next=head[u];        head[u]=cnt++;}void getroot(int u, int fa, int s){        int max1=0;        for(int i=head[u];i!=-1;i=edge[i].next){                int v=edge[i].v;                if(v==fa||vis[v]) continue ;                getroot(v,u,s);                max1=max(max1,siz[v]);        }        max1=max(max1,s-siz[u]);        if(min1>max1){                min1=max1;                root=u;        }}void getsize(int u, int fa){        siz[u]=1;        for(int i=head[u];i!=-1;i=edge[i].next){                int v=edge[i].v;                if(v==fa||vis[v]) continue ;                getsize(v,u);                siz[u]+=siz[v];        }}LL ksm(LL x){        LL ans=1;        int k=mod-2;        while(k){                if(k&1) ans=ans*x%mod;                k>>=1;                x=x*x%mod;        }        return ans;}void getF(int u, int fa, LL val){        F[tot].x=val;        F[tot++].num=u;        for(int i=head[u];i!=-1;i=edge[i].next){                int v=edge[i].v;                if(v==fa||vis[v]) continue ;                getF(v,u,val*a[v]%mod);        }}void work(int u){        vis[u]=1;        int i, j;        LL tmp;        for(i=head[u];i!=-1;i=edge[i].next){                int v=edge[i].v;                if(vis[v]) continue ;                min1=INF;                getsize(v,u);                getroot(v,u,siz[v]);                work(root);        }        ff++;        best[1]=u;        flag[1]=ff;        for(i=head[u];i!=-1;i=edge[i].next){                int v=edge[i].v;                if(vis[v]) continue;                tot=0;                getF(v,u,a[v]);                for(j=0;j<tot;j++){                        tmp=(LL)k*Inv[F[j].x*a[u]%mod]%mod;                        if(flag[tmp]!=ff) continue ;                        int minnum=min(best[tmp],F[j].num);                        int maxnum=max(best[tmp],F[j].num);                        if(ans1>minnum){                                ans1=minnum;                                ans2=maxnum;                        }                        else if(ans1==minnum&&ans2>maxnum) ans2=maxnum;                }                for(j=0;j<tot;j++){                        if(flag[F[j].x]!=ff||best[F[j].x]>F[j].num){                                best[F[j].x]=F[j].num;                                flag[F[j].x]=ff;                        }                }        }        vis[u]=0;}void init(){        memset(head,-1,sizeof(head));        cnt=0;        memset(vis,0,sizeof(vis));        ans1=ans2=INF;        memset(flag,-1,sizeof(flag));}void init1(){        Inv[0]=0;        for(int i=1;i<mod;i++){                Inv[i]=ksm((LL)i);        }}int main(){        int n, i, u, v;        init1();        while(scanf("%d%d",&n,&k)!=EOF){                init();                ff=0;                for(i=1;i<=n;i++){                        scanf("%I64d",&a[i]);                }                for(i=1;i<n;i++){                        scanf("%d%d",&u,&v);                        add(u,v);                        add(v,u);                }                min1=INF;                getsize(1,-1);                getroot(1,-1,n);                work(root);                if(ans1==INF) puts("No solution");                else printf("%d %d\n",ans1,ans2);        }        return 0;}

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.