zoukankan      html  css  js  c++  java
  • 点分治模板

    虽然说是一个模板题,但其实并不是那么模板……

    数据加强之后,N^2的时间复杂度是过不了的。注意到m只有一百,考虑先输入m个数,离线处理。

    代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    #define inf 0x3f3f3f3f
    const int maxn=25000;
    inline int read(){
        int x=0,f=1;
        char c=getchar();
        while(c>'9'||c<'0'){
            if(c=='-')f=-1;
            c=getchar();
        }
        while(c>='0'&&c<='9'){
            x=(x<<1)+(x<<3)+c-'0';
            c=getchar();
        }
        return x*f;
    }
    int beg[maxn],nex[maxn],to[maxn],w[maxn],e;
    void add(int x,int y,int z){
        e++;nex[e]=beg[x];
        beg[x]=e;to[e]=y;w[e]=z;
    }
    int n,m;
    int mx,size,rt;
    int sz[maxn],son[maxn];
    int vis[maxn],ans[20000005],top,st[maxn];
    inline void getrt(int x,int fa){
        sz[x]=1;son[x]=0;
        for(int i=beg[x];i;i=nex[i]){
            int t=to[i];
            if(t==fa||vis[t])continue;
            getrt(t,x);
            sz[x]+=sz[t];
            if(sz[t]>son[x])son[x]=sz[t];
        }
        if(size-sz[x]>son[x])son[x]=size-sz[x];
        if(son[x]<mx)mx=son[x],rt=x;
    }
    inline void query(int pos,int fa,int have){
        st[++top]=have;
        for(int i=beg[pos];i;i=nex[i]){
            int t=to[i];
            if(t==fa||vis[t])continue;
            query(t,pos,have+w[i]);
        }
    }
    int q[maxn],p,ask[maxn],test[maxn];
    inline void solve(int pos){
        p=0;ans[0]=1;
        for(int i=beg[pos];i;i=nex[i]){
            int t=to[i];
            if(vis[t])continue;
            top=0;
            query(t,pos,w[i]);
            for(int j=top;j;j--)
                for(int k=1;k<=m;k++)
                    if(ask[k]>=st[j])test[k]|=ans[ask[k]-st[j]];
            for(int j=1;j<=top;j++)
                q[++p]=st[j],ans[st[j]]=1;
        }
        for(int i=1;i<=p;i++)
            ans[q[i]]=0;
    }
    inline void devide(int x){
        vis[x]=1;
        solve(x);
        for(int i=beg[x];i;i=nex[i]){
            int t=to[i];
            if(vis[t])continue;
            mx=inf,size=sz[t],rt=0;
            getrt(t,0);
            devide(rt);
        }
    }
    int main(){
        n=read(),m=read();
        int x,y,z;
        for(int i=1;i<n;i++){
            x=read(),y=read(),z=read();
            add(x,y,z);
            add(y,x,z);
        }
        for(int i=1;i<=m;i++)
            ask[i]=read();
        mx=inf,size=n,rt=0;
        getrt(1,0);
        devide(rt);
        for(int i=1;i<=m;i++)
            puts(test[i]?"AYE":"NAY");
        return 0;
    } 

    请注意ans数组要尽量开大一点,不然会RE,QAQ。

  • 相关阅读:
    spring_150807_hibernate_transaction_annotation
    快速排序算法
    组合数递推算法
    HDU 4832 Chess(DP+组合数)
    HDU 2602 Bone Collector (01背包)
    HDU 1597 find the nth digit (二分查找)
    HDU1163 Eddy's digital Roots(九余数定理)
    HDU1031 Design T-Shirt (二级排序)
    HDU1719 Friend (数学推导)
    HDU1720 A+B Coming (16进制加法)
  • 原文地址:https://www.cnblogs.com/syzf2222/p/12386761.html
Copyright © 2011-2022 走看看