hdoj4812 D Tree (dotted rule)

Topic link: https: //vjudge.net/problem/HDU-4812

The meaning of problems: given a little right of the tree, find the point exists on a path of a weight equal to the value of the product modulo k, if the presence of multiple sets of points, minimum output lexicographically.

Ideas:

  Dotted rule template title. According to routine, to find the center of gravity, to obtain the right subtree node to the center of gravity value of the product after the mold takes a value dis [i] (including the weight of the center of gravity, nor may not include the same), with id [j] recorded end of the path, use the point of the second partition wording. Recursive, with a barrel Mine [i] to the center of gravity of the weight recorded volume of minimum number i. Then when looking for dis [J], meet the requirements tmp is: tmp * dis [j]% MOD = k * V [u], because the weight value comprises the center of gravity of our dis in, the weight center of gravity is multiplied twice. Then use the inverse element, tmp = k * V [u]% MOD * inv [dis [j]]% MOD. Update complete answer after the update barrel.

  Because not see the subject entitled to obtain points (a, b) is a <b, and I think that (a, a) are also met, then two hours to find the bug, crash to want to hammer the computer QAQ ....

AC Code:

#include<cstdio>
#include<algorithm>
#include<cctype>
#include<cstring>
using namespace std;

inline int read(){
    int x=0,f=0;char ch=0;
    while(!isdigit(ch)) {f|=ch=='-';ch=getchar();}
    while(isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    return f?-x:x;
}

typedef long long LL;
const int maxn=1e5+5;
const int MOD=1e6+3;
const int maxk=1e6+5;
const int inf=0x3f3f3f3f;
struct node1{
    int v,nex;
}edge[maxn<<1];

struct node2{
    int x,y;
    node2 () {x = y = 0 ;}
    node2(int x,int y):x(x),y(y){}
}years;

bool operator < (node2 a,node2 b){
    if(a.x==b.x) return a.y<b.y;
    return a.x<b.x;
}

int n,k,cnt,head[maxn],sz[maxn],mson[maxn],Min,root,size;
int vis[maxn],mine[maxk],id[maxn],t,tt;
LL V[maxn],dis[maxn],inv[maxk];

void init(){
    inv[1]=1;
    for(int i=2;i<maxk;++i)
        inv [i] = (v-v / i) * inv [v% to]% V;
}

void adde(int u,int v){
    edge [ ++ cnt] .v = v;
    edge[cnt].nex=head[u];
    head[u]=cnt;
}

void getroot(int u,int fa){
    sz[u]=1,mson[u]=0;
    for(int i=head[u];i;i=edge[i].nex){
        int v=edge[i].v;
        if(vis[v]||v==fa) continue;
        getroot (v, u);
        c [u] + = c [v];
        mson [u] = max (mson [u], sz [v]);
    }
    mson [u] = max (mson [u], size- sz [u]);
    f (mson [u] <Min) Min = mson [u], root = u;
}

void getdis(int u,int fa,LL len){
    dis[++t]=len,id[t]=u;
    for(int i=head[u];i;i=edge[i].nex){
        int v=edge[i].v;
        if(vis[v]||v==fa) continue;
        getdis (v, u, len * V [v]% MOD);
    }
}

void solve(int u){
    mine[V[u]]=u,t=0;
    for(int i=head[u];i;i=edge[i].nex){
        int v=edge[i].v;
        if(vis[v]) continue;
        tt=t;
        getdis(v,u,V[u]*V[v]%MOD);
        for(int j=tt+1;j<=t;++j){    
            LL tmp=1LL*k*V[u]%MOD*inv[dis[j]]%MOD;
            if(mine[tmp]==inf) continue;
            node2 other;
            if(mine[tmp]<id[j]) other.x=mine[tmp],other.y=id[j];
            else other.x=id[j],other.y=mine[tmp];
            if(other<ans) ans=other;
        }
        for(int j=tt+1;j<=t;++j)
            mine[dis[j]]=min(mine[dis[j]],id[j]);
    }
    mine[V[u]]=inf;
    for(int i=1;i<=t;++i)
        mine[dis[i]]=inf;
}

void fenzhi(int u,int ssize){
    Height [i] = 1 ;
    solve(u);
    for(int i=head[u];i;i=edge[i].nex){
        int v=edge[i].v;
        if(vis[v]) continue;
        Min=inf,root=0;
        size=sz[v]<sz[u]?sz[v]:(ssize-sz[u]);
        getroot (v, 0 );
        fenzhi(root,size);
    }
}

int main () {
    init();
    memset(mine,0x3f,sizeof(mine));
    while(~scanf("%d%d",&n,&k)){
        cnt=0;
        ans.x=ans.y=n+1;
        for(int i=0;i<=n;++i)
            head[i]=vis[i]=0;
        for(int i=1;i<=n;++i){
            int tmp=read();
            V[i]=tmp;
        }
        for(int i=1;i<n;++i){
            int u=read(),v=read();
            adde (u, v);
            adde (v, u);
        }
        Min=inf,root=0,size=n;
        getroot ( 1 , 0 );
        fenzhi (root, n);
        if(ans.x==n+1)
            printf("No solution\n");
        else
            printf("%d %d\n",ans.x,ans.y);
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/FrankChen831X/p/11391489.html