zoukankan      html  css  js  c++  java
  • Solution -「CF 1039D」You Are Given a Tree

    Description

    Link.

    有一棵 (n) 个节点的树,其中一个简单路径的集合被称为 (k) 合法当且仅当:树的每个节点至多属于其中一条路径,且每条路径恰好包含 (k) 个点。

    对于 (kin [1,n]),求出 (k) 合法路径集合的最多路径数。

    即:设 (k) 合法路径集合为 (S),求最大的 (|S|)

    Solution

    (f(i))(k=i) 时的答案,因为限定了每条路径的结点数,所以 (f(i)lelfloorfrac{n}{i} floor),差不多可以看出 (f(i)) 是单调不增的。

    然后仔细看这个形式,是不是长得很像数论分块?所以连续 (f(i)) 相同的值的块长为至少 (sqrt{n})

    然后枚举左端点,二分找右端点,求解 (f(i)) 应该是常见 trick。

    听说直接二分常数很大,所以要写整体二分。我也不会卡常,所以就写整体二分叭。

    #include<bits/stdc++.h>
    int n,ans[100010],delta,f[100010];
    int head[100010],nxt[200010],to[200010],cntot;
    void addEdge(int one,int ano) {
    	to[++cntot]=ano;
    	nxt[cntot]=head[one];
    	head[one]=cntot;
    }
    void dfs(int x,int las,int rule) {
    	int fs=0,sc=0;
    	for(int i=head[x];i;i=nxt[i]) {
    		int y=to[i];
    		if(y^las) {
    			dfs(y,x,rule);
    			if(f[y]>=fs) {
    				sc=fs;
    				fs=f[y];
    			}
    			else if(f[y]>=sc)	sc=f[y];
    		}
    	}
    	if(fs+sc+1>=rule) {
    		f[x]=0;
    		++delta;
    	}
    	else	f[x]=fs+1;
    }
    void rawGrass(int l,int r,int fr,int ba) {
    	if(l>r || fr>ba)	return;
    	if(l^r) {
    		int mid=(fr+ba)>>1;
    		delta=0;
    		dfs(1,0,mid);
    		ans[mid]=delta;
    		rawGrass(delta,r,fr,mid-1);
    		rawGrass(l,delta,mid+1,ba);
    	}
    	else {
    		for(int i=fr;i<=ba;++i)	ans[i]=l;
    	}
    }
    void read(int &hhh) {
    	int x=0,f=1;
    	char c=getchar();
    	while(c<'0' || c>'9')	c=getchar();
    	while(c>='0' && c<='9') {
    		x=(x<<3)+(x<<1)+(c^'0');
    		c=getchar();
    	}
    	hhh=x;
    }
    void write(int x,char las='
    ') {
    	static int stack[100],top=0;
    	do {
    		stack[++top]=x%10;
    		x/=10;
    	}while(x);
    	while(top)	putchar(stack[top--]^'0');
    	putchar(las);
    }
    int main() {
    	read(n);
    	for(int i=1,x,y;i<n;++i) {
    		read(x);
    		read(y);
    		addEdge(x,y);
    		addEdge(y,x);
    	}
    	rawGrass(0,n,1,n);
    	for(int i=1;i<=n;++i)	write(ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    node.js学习二---------------------同步API和异步API的区别
    node.js学习一---------------------模块的导入
    ES6函数的特性(箭头语法)
    10分钟了解Android的Handler机制
    10分钟了解Android的事件分发
    SwipeRefreshLayout,用最少的代码定制最美的上下拉刷新样式
    手把手教你React Native 实战之开山篇《一》
    Android 组件化方案探索与思考
    2018谷歌I/O开发者大会8大看点汇总 新品有哪些
    Glide高级详解—缓存与解码复用
  • 原文地址:https://www.cnblogs.com/orchid-any/p/14627378.html
Copyright © 2011-2022 走看看