zoukankan      html  css  js  c++  java
  • BZOJ 2783 JLOI 2012 树 乘+二分法

    标题效果:鉴于一棵树和一个整数s,问中有树木几个这样的路径,点和担保路径==s,深度增量点。

    这一数额的输出。


    思维:用加倍的想法,我们可以O(logn)在时间找点他第一n。因为点权仅仅能是正的,满足二分性质。然后对于每个点二分。看看有没有路径的权值和是S。统计答案,输出。


    CODE:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define MAX 100010
    using namespace std;
    
    int points,s;
    int src[MAX];
    int head[MAX],total;
    int next[MAX << 1],aim[MAX << 1];
    
    int father[MAX][20],length[MAX][20];
    
    inline void Add(int x,int y);
    void DFS(int x,int last);
    void SparseTable();
    
    inline bool Judge(int x);
    inline int GetLength(int x,int deep);
    
    int main()
    {
    	cin >> points >> s;
    	for(int i = 1;i <= points; ++i)
    		scanf("%d",&src[i]);
    	for(int x,y,i = 1;i < points; ++i) {
    		scanf("%d%d",&x,&y);
    		Add(x,y),Add(y,x);
    	}
    	DFS(1,0);
    	SparseTable();
    	int ans = 0;
    	for(int i = 1;i <= points; ++i)
    		ans += Judge(i);
    	cout << ans << endl;
    	return 0;
    }
    
    inline void Add(int x,int y)
    {
    	next[++total] = head[x];
    	aim[total] = y;
    	head[x] = total;
    }
    
    void DFS(int x,int last)
    {
    	father[x][0] = last;
    	length[x][0] = src[last];
    	for(int i = head[x];i;i = next[i]) {
    		if(aim[i] == last)	continue;
    		DFS(aim[i],x);
    	}
    }
    
    void SparseTable()
    {
    	for(int j = 1;j <= 19; ++j)
    		for(int i = 1;i <= points; ++i) {
    			father[i][j] = father[father[i][j - 1]][j - 1];
    			length[i][j] = length[i][j - 1] + length[father[i][j - 1]][j - 1];
    		}
    }
    
    inline bool Judge(int x)
    {
    	int l = 0,r = 100000;
    	while(l <= r) {
    		int mid = (l + r) >> 1;
    		int length = GetLength(x,mid) + src[x];
    		if(length < s)	l = mid + 1;
    		else if(length > s)	r = mid - 1;
    		else	return true;
    	}
    	return false;
    }
    
    inline int GetLength(int x,int deep)
    {
    	int re = 0;
    	for(int i = 19; ~i; --i)
    		if(deep - (1 << i) >= 0) {
    			deep -= 1 << i;
    			re += length[x][i];
    			x = father[x][i];
    		}
    	return re;
    }
    


    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    详解package-lock.json的作用
    Cisco计网实验配置总结
    使用Vue制作了一个计算机网络中子网划分部分的简陋计算工具
    Prettier-Code Formater代码格式化插件使用教程
    Node.js中npx命令的使用方法、场景
    从几道题目带你深入理解Event Loop_宏队列_微队列
    简单模拟实现javascript中的call、apply、bind方法
    git使用说明书
    使用闭包模拟实现AMD模块化规范
    if执行后else if即使满足条件也不再执行
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4674412.html
Copyright © 2011-2022 走看看