首页 > 其他分享 >cf1856E2. PermuTree (hard version)(bitset+二进制优化背包+开不同大小bitset)

cf1856E2. PermuTree (hard version)(bitset+二进制优化背包+开不同大小bitset)

时间:2023-11-07 16:00:36浏览次数:44  
标签:cf1856E2 PermuTree num bitset return include ll define

https://codeforces.com/contest/1856/problem/E2

结论是显然的,关键是有一些科技在里面

bitset+二进制优化

具体分析可以参考https://codeforces.com/blog/entry/98663
简而言之就是可以通过\(O(\frac{C\sqrt C}{w})\)的复杂度判断是否能够获得某种体积

开不同大小bitset

template<int len = 1>
void solve(ll s) {
	if (len <= s) {
		solve<min(len*2,N)>(s);
		return;
	}

当然要c++14及以上才能支持

剪枝

不过感觉这个剪枝可能只对这道题比较有用,当一个子树的大小大于其它的和,那么肯定是这个分一组,剩下的分一组。
具体复杂度分析见https://codeforces.com/blog/entry/119058

科技拉满的一道题。
虽然感觉以后也遇不到,但还是很有意思。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<vector>
#include<set>
#include<ctime>
#include<unordered_map>
#include<queue>
#include<bitset>
#include<iostream>
#define A puts("YES")
#define B puts("NO")
#define fo(i,a,b) for (ll (i)=(a);(i)<=(b);(i)++)
#define fd(i,b,a) for (int (i)=(b);(i)>=(a);(i)--)
#define mk(x,y) make_pair((x),(y))
#define lc (o<<1)
#define rc (o<<1|1)
using namespace std;
//typedef __int128 i128;
typedef double db;
typedef long long ll;
//const ll mo=1e9+7;
//const int inf=1<<30;
const int N = 1e6 + 5;
int head[N], to[N], nex[N], tot, n, x;
int m;
ll a[N], s[N], ans;
vector<ll> b;

void add(int x, int y) {
	to[++tot] = y; nex[tot] = head[x]; head[x] = tot;
}
bool cmp(ll a, ll b) {
	return a > b;
}
template<int len = 1>
void solve(ll s) {
	if (len <= s) {
		solve<min(len*2,N)>(s);
		return;
	}

	bitset<len> f;
	f[0] = 1;

	for (ll x:b) f |= f << x;
	ll mx = 0;
	fo(i, 1, s) {
		if (f[i]) mx = max(mx, i*(s-i-1));
	}
	ans += mx;

}
void dfs(int x) {
	s[x] = 1; //
	for (int i = head[x]; i; i = nex[i]) {
		int v = to[i];
		dfs(v);
		s[x] += s[v];
	}

	m = 0;

	for (int i = head[x]; i; i = nex[i]) {
		int v = to[i];
		a[++m] = s[v];
	}
	a[++m] = 0;
	sort(a + 1, a + m + 1, cmp);

	if (a[1] >= s[x] / 2) {                                                        
		ans += a[1] * (s[x] - 1 - a[1]);
		return;
	}

	b.clear(); 
	ll l = 0, num;
	fo(i, 1, m-1) {
		if (a[i] != a[i+1]) {
			num = i - l;
			ll j = 1;

			while (j < num) {
				b.emplace_back(j * a[i]);
				num -= j;
				j <<= 1;
			}
			b.emplace_back(num * a[i]);

			l = i;
		}
	}

	solve(s[x]);
}
int main()
{
	//	freopen("data.in","r",stdin);
	//	freopen("data.out","w",stdout);


	std::ios::sync_with_stdio(false);
		
	cin >> n;
	fo(i, 2, n) {
		cin >> x;
		add(x, i);
	}
	dfs(1);
	cout << ans;
	return 0;
}



标签:cf1856E2,PermuTree,num,bitset,return,include,ll,define
From: https://www.cnblogs.com/ganking/p/17815193.html

相关文章

  • bitset用法
    1、简介bitset在bitset头文件中,它类似数组,并且每一个元素只能是0或1,每个元素只用1bit空间。//头文件#include<bitset>2、初始化定义初始化方法代码含义bitsetaa有n位,每位都为0bitseta(b)a是unsignedlong型u的一个副本bitseta(s)a是string对象s中含有......
  • 【bitset】【线段树】CF633G Yash And Trees 题解
    CF633G简单题。先看到子树加和子树质数个数和,果断转换为dfs序进行处理。既然有区间求和,考虑线段树。若对于每一个节点维护一个\(cnt\)数组,用二进制数\(x\)来表示,即当\(cnt_i=1\)时第\(i\)位为\(1\)。设当前节点为\(u\),左右子节点分别为\(ls\)和\(rs\)。发现......
  • C++ bitset 用法和应用
    C++的bitset在bitset头文件中,它是一种类似数组的结构,它的每一个元素只能是0或1,每个元素仅用1bit空间。下面是具体用法构造函数bitset常用构造函数有四种,如下bitset<4>bitset1;//无参构造,长度为4,默认每一位为0bitset<8>bitset2(12);//长度为8,二进制保存,前......
  • bitset 求解高维偏序
    菜,题简单,trick蠢,求别骂。记录今天做题的时候遇到的一个小trick。先看一道题:P3810【模板】三维偏序(陌上花开)。平凡的三维偏序板子,相信大家都会用CDQ/树套树/K-Dtree之类的优秀做法秒了吧!然后看这个题:求五维偏序,\(n\le3\times10^4\),保证每一维这\(n\)个数都是\(n\)......
  • STL——bitset的使用方法
    bitset介绍类似\(bool\)数组一样的东西,储存的是二进制,但是每一位只占\(1bit\),可以优化你算法的时间和空间复杂度。储存开一个bitset为:bitset<100>bs;最左边为最低位(即第\(0\)位),最右边为最高位。在初始化的时候,是从最低位开始储存。初始化有两种初始化整数bitse......
  • bitset 优化莫队
    题目传送门:Ynoi跳进兔子洞好题!我们观察题目,发现题目让我们求的可以写成:\[(r_1-l_1+1)+(r_2-l_2+1)+(r_3-l_3+1)-3\timessize\]其中:\(size\)是三段中公共颜色的个数问题转移成求三段公共颜色的个数。考虑使用莫队,然后在转换左右边界的时候使用数组记录每个颜色出现几次,然后......
  • H. Needle[FFT]或bitset
    Problem-H-Codeforces题意是给三面墙(简化为一条轴),然后给墙上的洞(简化成点),问多少直线可以从第一面墙穿出第三面墙。要使三点共线,那么(b-a)=(c-b)即(a+c)=2*b由于n是1e5所以O(n2)会超时。有两种做法1.本题的任意两数相加的步骤类似多项式乘法,我们把a,c看成两个多项式的系......
  • Codeforces Round 889 (Div. 1) B. Earn or Unlock(dp,bitset)
    题目链接:https://codeforces.com/problemset/problem/1854/B 题目大致题意: 有n张卡牌从上到下堆叠,每张卡片有锁或不锁俩种状态,一开始第一张是不锁的;对最上面的卡牌,如果他是不锁的状态,那么可以进行俩种操作:1:从上到下,将v张被锁的卡牌解锁;2:获取v点能量现在求能获得的最大的......
  • bitset优化01可行背包
    例题传送门:『STA-R3』Aulvwc先讲bitset用法:1,基础下标:\(5~4~3~2~1~0\)数字:\(0~0~0~0~1~0\)\(bitset\)<\(n\)>\(s\)表示一个\(n\)位的二进制数,空间复杂度:\(O(\frac{n}{32})\),可见其非常优秀因为其跟二进制有关,所以可以使用\(\&,|,\land\)对两个位数相同的\(bitset\)执行按......
  • AOJ0525(bitset, 穷举)
    这题有3点要注意:1.thefliporderisnotrelatedtoresult.2.whywecansimplycounttomaximumofnumbereachcolumn?Imagineonlymanipulatetherow,itiseasytounderstandthatitisunnecessarytoflipthemratherthancountthemaximumside.3.Aga......