hdu4812 D Tree 点分治

这里要求输出字典序最小的两个点,就不能像之前那样容斥了,只能直接搞了。

直接搞的话,需要避开n^2,由于这里是等式,显然应该考虑hash映射。从前往后依次枚举计算每棵子树,对于每个子树结点,快速从前面已经计算过的子树中找到答案更新就可以了。

很简单的东西,只是难以用文字解释得清楚。大概一般点分治不用容斥直接搞大多是这样干吧。

#pragma comment(linker,"/STACK:102400000,102400000")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1e9+10;

template<class T>
inline void scan(T &ret)
{
    char c=getchar();
    while(!isdigit(c)) c=getchar();
    ret=c-'0';
    while(isdigit(c=getchar())) ret=ret*10+c-'0';
}

inline void out(int a)
{
    if(a>9) out(a/10);
    putchar(a%10+'0');
}

const ll MOD=1e6+3;
int N,K;
int val[maxn];
//vector<int> G[maxn];
int u,v;
int ans1,ans2;
int id[maxn];
int d[maxn],dn;
ll s[maxn];
bool vis[maxn];
int rt,balance;
int Inv[maxn];
int e[maxn],tot;
int first[maxn],Next[maxn];

void Init()
{
    tot=0;
    memset(first,-1,sizeof(first));
}

void addedge(int u,int v)
{
    e[++tot]=v;
    Next[tot]=first[u];
    first[u]=tot;
}

ll mul(ll a,ll b,ll MOD)
{
    return (a*b)%MOD;
}

ll qpow(ll n,ll k,ll p)
{
    ll res=1;
    while(k){
        if(k&1) res=(res*n)%p;
        n=(n*n)%p;
        k>>=1;
    }
    return res;
}

void dfs_d(int u,int f,ll dep)
{
    d[++dn]=u;
    s[u]=dep;
    //for(int i=0;i<G[u].size();i++){
    for(int p=first[u];~p;p=Next[p]){
        int v=e[p];
        if(v==f||vis[v]) continue;
        dfs_d(v,u,mul(dep,val[v],MOD));
    }
}

ll inv(ll a,ll p)
{
    return qpow(a,p-2,p);
}

void update(int x,int y)
{
    if(x>y) swap(x,y);
    if(x<ans1) ans1=x,ans2=y;
    else if(x==ans1){
        if(y<ans2) ans1=x,ans2=y;
    }
}

int get_rt(int u,int f,int sz)
{
    int cnt=1,balance1=0;
    for(int p=first[u];~p;p=Next[p]){
        int v=e[p];
        if(v==f||vis[v]) continue;
        int tmp=get_rt(v,u,sz);
        cnt+=tmp;
        balance1=max(balance1,tmp);
    }
    balance1=max(balance1,sz-cnt);
    if(balance1<balance){
        balance=balance1;
        rt=u;
    }
    return cnt;
}

void cls_id(int u,int f)
{
    id[s[u]]=0;
    //for(int i=0;i<G[u].size();i++){
    for(int p=first[u];~p;p=Next[p]){
        int v=e[p];
        if(v==f||vis[v]) continue;
        cls_id(v,u);
    }
}

void solve(int u)
{
    rt=u,balance=INF;
    int sz=get_rt(u,0,N);
    rt=u,balance=INF;
    get_rt(u,0,sz);
    u=rt;
    //cout<<"u="<<u<<endl;
    vis[u]=1;
    id[val[u]]=u;
    s[u]=val[u];
    //for(int i=0;i<G[u].size();i++){
    for(int p=first[u];~p;p=Next[p]){
        int v=e[p];
        if(vis[v]) continue;
        dn=0;
        dfs_d(v,u,mul(val[u],val[v],MOD));
        //cout<<" v="<<v<<" dn="<<dn<<endl;
        //REP(j,1,dn) cout<<d[j]<<"_";cout<<endl;
        int idx,x,idy;
        REP(j,1,dn){
            idx=d[j],x=s[idx];
            idy=id[mul(mul(K,val[u],MOD),Inv[x],MOD)];
            if(idy) update(idx,idy);
        }
        REP(j,1,dn){
            idx=d[j],x=s[idx];
            if(id[x]) id[x]=min(id[x],idx);
            else id[x]=idx;
        }
    }
    cls_id(u,0);
    //for(int i=0;i<G[u].size();i++){
    for(int p=first[u];~p;p=Next[p]){
        int v=e[p];
        if(vis[v]) continue;
        solve(v);
    }
}

void play()
{
    freopen("in.txt","w",stdout);
    int n=10000,k=120;
    cout<<n<<" "<<k<<endl;
    REP(i,1,n) cout<<i<<" ";cout<<endl;
    REP(i,1,n-1){
        cout<<i<<" "<<i+1<<endl;
    }
}

void Init_inv()
{
    REP(i,0,MOD-1) Inv[i]=inv(i,MOD);
}

int main()
{
    //play();return 0;
    freopen("in.txt","r",stdin);
    Init_inv();
    while(~scanf("%d%d",&N,&K)){
        Init();
        REP(i,1,N) scan(val[i]),val[i]%=MOD;
        REP(i,1,N-1){
            //scanf("%d%d",&u,&v);
            scan(u);scan(v);
            addedge(u,v);
            addedge(v,u);
        }
        ans1=ans2=INF;
        MS0(vis);MS0(id);
        solve(1);
        if(ans1==INF) puts("No solution");
        else{ //printf("%d %d\n",ans1,ans2);
            out(ans1);
            putchar(' ');
            out(ans2);
            putchar('\n');
        }
    }
    return 0;
}
View Code

TLE了几次,以为是算法问题,看标程都加了输入输出挂,我也加了试交一下,过了。。。是在下输了。。。

 

转载于:https://www.cnblogs.com/--560/p/5280469.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值