码迷,mamicode.com
首页 > 其他好文 > 详细

10月——备战区域赛

时间:2015-10-06 18:13:25      阅读:290      评论:0      收藏:0      [点我收藏+]

标签:

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;
}
View Code

 

10月——备战区域赛

标签:

原文地址:http://www.cnblogs.com/Cw-trip/p/4857427.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!