首页 > 其他分享 >CERC 17 J - Justified Jungle

CERC 17 J - Justified Jungle

时间:2024-08-02 14:19:26浏览次数:6  
标签:删除 子树 CERC 17 int nex 大小 Justified include

传送门

题意

时限6s, 给你一颗\(n \leq 1e6\)的树,输出所有的\(i\), 使得该树可以删除某\(i\)条边,使得删除后所有的连通块大小相等

题解

虽然有结论,但还是讲讲我的做法把, 或许有所启发
考虑将枚举删除边数转换为枚举连通块大小, 不妨设每个连通块大小为\(k\)

每次从树上删除一个大小恰为\(k\)的子树,如果这样可以删除整棵树,那么就可以,否则不行,正确性应该比较正确?

如何实现呢? 如果我们能够在较小的复杂度实现发现并删除一颗大小为\(k\)的子树,那么总复杂度就是调和级数级别的

考虑这样做: 我们预处理子树大小, 把每一个点按子树大小丢入一个桶中, 对于每一个\(k\), 我们从小到大扫描它的倍数, 用线段树加dfs序维护删除后的子树大小, 一开始把所有\(k\)大小的子树删除了,然后对于所有\(2k\)桶中的子树,他们当前的大小如果是\(k\)就删除,如果不是\(k\)就无解。

总复杂度\(O(nlog^2n)\)

实现

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#define ls(x) (x*2)
#define rs(x) (x*2+1) 
#define ll long long 
using namespace std;

int read(){
	int num=0, flag=1; char c=getchar();
	while(!isdigit(c) && c!='-') c=getchar();
	if(c == '-') flag=-1, c=getchar();
	while(isdigit(c)) num=num*10+c-'0', c=getchar();
	return num*flag;
}

const int N = 1e6+10000;
int n;
vector<int> p[N];
int fa[N], dis[N], son[N], dfn[N], efn[N], cnt=0;

void dfs(int x){
	son[x] = 1;
	dfn[x] = ++cnt;
	for(auto nex : p[x]){
		if(nex == fa[x]) continue;
		fa[nex] = x;
		dis[nex] = dis[x] + 1;
		dfs(nex);
		son[x] += son[nex];
	}
	efn[x] = cnt;
}

struct Tree{
	int tree[N<<2];
	
	void push_up(int o){
		tree[o] = tree[ls(o)] + tree[rs(o)];
	}
	
	void build(int o, int l, int r){
		if(l == r){
			tree[o] = 1;
			return ;
		}
		
		int mid =(l+r)/2;
		if(tree[ls(o)] != (mid-l+1)) build(ls(o), l, mid);
		if(tree[rs(o)] != (r-mid)) build(rs(o), mid+1, r);
		push_up(o);
	}
	
	int query(int o, int l, int r, int ql, int qr){
		if(ql<=l && r<=qr) return tree[o];
		int mid=(l+r)/2, res=0;
		
		if(ql<=mid) res+=query(ls(o),l,mid, ql,qr);
		if(qr>mid) res+=query(rs(o), mid+1, r, ql,qr); 
		return res;
	} 
	
	void update(int o, int l, int r, int x, int v){
		if(l == r){
			tree[o] += v;
			return ;
		}
		
		int mid = (l+r)/2;
		if(x <= mid) update(ls(o),l,mid, x,v);
		else update(rs(o),mid+1,r, x,v);
		push_up(o);
	}
}t;
vector<int> s[N];


int check(int k){
	t.build(1,1,n);
	for(int i=1; i*k<=n; i++){
		for(auto x : s[i*k]){
			if(t.query(1,1,n,dfn[x],efn[x]) != k) return 0;
			t.update(1,1,n,dfn[x],-k);
		}
	}
	return 1;
}



int main(){
	n = read();
	for(int i=1; i<=n-1; i++){
		int u=read(), v=read();
		p[u].push_back(v);
		p[v].push_back(u);
	}
	
	dis[1] = 1;
	dfs(1);
	
	for(int i=1; i<=n; i++){
		s[son[i]].push_back(i);
	}
	
	for(int i=n-1; i>=1; i--){
		if(n % i) continue;
		if(check(i)){
			printf("%d ", n/i-1);
		}
	} 
	return 0;
} 









标签:删除,子树,CERC,17,int,nex,大小,Justified,include
From: https://www.cnblogs.com/ltdjcoder/p/18338657

相关文章

  • Day17 二叉树Part5
    目录任务654.最大二叉树思路617.合并二叉树思路700.二叉搜索树中的搜索思路98.验证二叉搜索树思路(错误)思路(正确)心得体会任务654.最大二叉树给定一个不重复的整数数组nums。最大二叉树可以用下面的算法从nums递归地构建:创建一个根节点,其值为nums中的最大值。递归......
  • 代码随想录day17 || 654 最大二叉树,617 合并二叉树,700 二叉搜索树搜索,98 验证二叉搜索
    645最大二叉树funcconstructMaximumBinaryTree(nums[]int)*TreeNode{ //思路,算法思路基本等同于通过中序前序构造二叉树 //1,取最大值作为根节点 //2,切割数组 //3,递归左右子树 iflen(nums)==0{ returnnil } //切割数组取最大值 max,left,right:=......
  • 2024暑假集训测试17
    前言比赛链接。T1没加记忆化莫名原因T飞了,T2没做过IO交互不知道咋测样例干脆没交,T3到现在还不知道为啥爆零了,赛时不知道咋合并背包根本不敢打,离线下来寻思快点结果全死了,T4不可做题。还是老毛病,遇到之前见的不多题型(尤其是T1、T2放)就寄,这次T1倒是没卡住(但是挂分......
  • 力扣2173题
    力扣之2173.最多连胜的次数说明跳转准备工作dropdatabaseifexistsdb_1;createdatabasedb_1;usedb_1;CreatetableIfNotExistsMatches(player_idint,match_daydate,resultENUM('Win','Draw','Lose'));TruncatetableMatches;inser......
  • 每天学一个 Linux 命令(17):chmod
    命令简介chmod命令用来变更文件或目录的权限。文件或目录权限有读取、写入、执行这3种,另外还有3种特殊权限。用户可以使用chmod去设置文件与目录的权限,设置方式采用文字或数字皆可。链接文件的权限无法直接变更,如果用户需要对链接文件修改权限,其真实作用是作用在原始文件上。......
  • Apple Safari 17.6 - macOS 专属浏览器 (独立安装包下载)
    AppleSafari17.6-macOS专属浏览器(独立安装包下载)适用于macOSVentura和macOSMonterey的Safari浏览器17请访问原文链接:https://sysin.org/blog/apple-safari-17/,查看最新版。原创作品,转载请保留出处。之前Safari浏览器伴随macOS更新一起发布,需要系统更新才......
  • ctfshow-web入门-sql注入(web171-web175)
    目录1、web1712、web1723、web1734、web1745、web1751、web171单引号测一下,报错 --+闭合后回显正常 也可以用#,不过需要URL编码成功闭合之后,先判断下字段数:1'orderby3--+3的时候正常 4的时候报错,说明只有3列  测了一下,三个回显位都能正......
  • 洛谷-P1171-售货员的难题
    Abstract传送门也算是状压dp模板题?不过这个数据给的有点阴间了,空间不够用,需要搞一个奇妙的优化。idea所谓状压,就是用数字表示当前状态,比如说0110100这个数字,我们可以把01分别看作是是否到达过第i个点的标记。那么我们可以用dp[i][j]表示第i个状态下,快递员到达j......
  • P3957 [NOIP2017 普及组] 跳房子
    思路:首先发现单调性,灵活性增加\(x+1\)的答案肯定不会比增加\(x\)的答案更劣。那么可以二分求\(g\),则机器人每次可以移动\([\max(d-mid,1),d+mid]\)这个区间内的距离,为了方便,设为\([l,r]\)。考虑动态规划求得能走到的最大分数,令\(dp_i\)表示走到第\(i\)个格子的最大......
  • [HITCON 2017]SSRFme 1
    目录代码审计@符号shell_exec()函数:GET".escapeshellarg($_GET["url"]):pathinfo($_GET["filename"]basename()题目解析代码审计118.182.186.90<?phpif(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){$http_x_headers=explod......