zoukankan      html  css  js  c++  java
  • LuoguP3806 【模板】点分治1 (点分治)

    给定一棵有n个点的树,询问树上距离为k的点对是否存在。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #define R(a,b,c) for(register int  a = (b); a <= (c); ++ a)
    #define nR(a,b,c) for(register int  a = (b); a >= (c); -- a)
    #define Max(a,b) ((a) > (b) ? (a) : (b))
    #define Min(a,b) ((a) < (b) ? (a) : (b))
    #define Fill(a,b) memset(a, b, sizeof(a))
    #define Swap(a,b) a^=b^=a^=b
    #define ll long long
    #define ON_DEBUG
    
    #ifdef ON_DEBUG
    
    #define D_e_Line printf("
    
    ----------
    
    ")
    
    #else
    
    #define D_e_Line ;
    
    #endif
    
    struct ios{
        template<typename ATP>ios& operator >> (ATP &x){
            x = 0; int f = 1; char c;
            for(c = getchar(); c < '0' || c > '9'; c = getchar()) if(c == '-')  f = -1;
            while(c >= '0' && c <= '9') x = x * 10 + (c ^ '0'), c = getchar();
            x*= f;
            return *this;
        }
    }io;
    using namespace std; 
    const int N = 10007;
    const int MAXX = 10000000;
    
    struct Edge{
    	int nxt,pre,w;
    }e[N<<1];
    int cntEdge,head[N];
    inline void add(int u,int v,int w){
    	e[++cntEdge] = (Edge){head[u], v, w}, head[u] = cntEdge;
    }
    
    int minn, root, treeSize;
    
    int vis[N],siz[N];
    inline void GetRoot(int u,int fa){
    	siz[u] = 1;
    	int sum = 0;
    	for(register int i = head[u]; i; i = e[i].nxt){
    		int v = e[i].pre;
    		if(vis[v] || v == fa) continue;
    		GetRoot(v, u);
    		sum = Max(sum, siz[v]);
    		siz[u] += siz[v];
    	}
    	sum = Max(sum, treeSize - siz[u]);
    	if(sum < minn){
    		minn = sum;
    		root = u;
    	}
    }
    
    int dis[N];
    
    int tot;
    inline void GetDistance(int u,int fa,int w){
    	dis[++tot] = w;
    	for(register int i = head[u]; i; i = e[i].nxt){
    		int v = e[i].pre;
    		if(vis[v] || v == fa) continue;
    		GetDistance(v, u, w + e[i].w);
    	}
    }
    
    int num[MAXX];
    inline void Solve(int u,int w,int flag){ // w is the influence of the beginning node
    	tot = 0;
    	GetDistance(u, u, 0);
    	R(i,1,tot){
    		R(j,1,tot){
    			if(flag && dis[i] + dis[j] <= MAXX)
    				++ num[dis[i] + dis[j]];
    			else
    				if(dis[i] + dis[j] +w <= MAXX)
    					-- num[dis[i] + dis[j] + w];
    		}
    	}
    }
    
    inline void DFS(int u){
    	Solve(u, 0, 1);
    	vis[u] = true;
    	for(register int i = head[u]; i; i = e[i].nxt){
    		int v = e[i].pre;
    		if(vis[v]) continue;
    		Solve(v, (e[i].w << 1), 0); // QAQ //  T^T /
    		treeSize = siz[v];
    		minn = 0x7fffffff;
    		GetRoot(v, u);
    		DFS(root);
    	}
    }
    
    int main(){
    	int n,m;
    	io >> n >> m;
    	R(i,2,n){
    		int u,v,w;
    		io >> u >> v >> w;
    		add(u, v, w);
    		add(v, u, w);
    	}
    	
    	treeSize = n; // because I forgot this sentence, the whole morning...
    	minn = 0x7fffffff;
    	GetRoot(1, 1);
    	DFS(root);
    	
    	while(m--){
    		int x;
    		io >> x;
    		if(num[x])
    			printf("AYE
    ");
    		else
    			printf("NAY
    ");
    	}
    	
    	return 0;
    }
    

    a faster way in some cases

    inline int Solve(int u,int w){
    	tot = 0;
    	GetDistance(u, u, 0);
    	sort(dis + 1, dis + tot + 1);
    	int l = 0, r = tot;
    	while(l < r){
    		while(l < r && dis[l] + dis[r] > MAXX) -- r;
    		ans += r - l;
    		++ l;
    	}
    	return ans;
    }
    

  • 相关阅读:
    团队活动
    实力提升
    软工人必须要知道的几个工具
    博客/论坛:(技术分享)
    CSS怎样设置多个字体,设置多个字体的时候要注意什么
    canvas绘制bitmap全部填充(当bitmap的宽高小于绘制区域的时候)
    CSS字体
    weditor元素定位异常
    python ImportError: C extension: DLL load failed while importing strptim
    python:导入不同路径下相同名称的模块
  • 原文地址:https://www.cnblogs.com/bingoyes/p/11194071.html
Copyright © 2011-2022 走看看