ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

A层省选6

2022-08-18 08:00:59  阅读:141  来源: 互联网

标签:层省 rs int cc nans include select2


A. T1

考虑每一位对\(f\)的贡献,假设有\(x\)个\(a_i\)该位为\(1\)

code
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
inline ll read(){
	ll x = 0; char c = getchar();
	while(c < '0' || c > '9')c = getchar();
	do{x = (x << 3) + (x << 1) + (c ^ 48); c = getchar();}while(c <= '9' && c >= '0');
	return x;
}
const int maxn = 100005;
ll n, l, r;
ll work(){
	if(l == r)return 1;
	int hi = 0;  for(int i = 63; i >= 0; --i)if(((1ll << i) & l) != ((1ll << i) & r)){hi = i; break;}
	int low = -1; for(int i = hi - 1; i >= 0; --i)if(r & (1ll << i)){low = i; break;}
	ll nans = (1ll << hi) - (l & ((1ll << hi) - 1)), rl = (1ll << hi) - nans;
	ll lr = (1ll << (low + 1)) - 1;
	nans = nans << 1;
	return nans + min(lr, rl - 1) + 1;
}
int main(){
	freopen("a.in", "r", stdin);
	freopen("a.out", "w", stdout);
	int T = read();
	for(register int ask = 1; ask <= T; ++ask){
		n = read(), l = read(), r = read();
		if(n > 1)printf("%lld\n",work());
		else printf("%lld\n", r - l + 1);
	}
	return 0;
}

B. T2

考场刚推出对称差虎哥就发解释了..

这题先说对于任意四元组,在一棵树上有且仅有一种划分

划分在同一侧的两组在树上路径没有交,中间有一条链相连

于是我们可以枚举删去一条边或者一个点来容斥

由于一个四元组在边上统计的次数比在点上统计的次数多\(1\),所以加上删边的贡献,减去删点的贡献

然后我们枚举在第一棵树上删了啥,对删除后在不同块的树点进行染色,在第二棵树上统计交集(枚举删去点/边,选所有不同颜色的组合,分别在不同子树内选取某种颜色的二元组),根据点/边决定是加上还是减去

这样$ S \Delta S^,= 2 \times C_{leaf}^4 - ans$

uglycode
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<assert.h>
using namespace std;
typedef long long ll;
inline int read(){
	int x = 0; char c = getchar();
	while(c < '0' || c > '9')c = getchar();
	do{x = (x << 3) + (x << 1) + (c ^ 48); c = getchar();}while(c <= '9' && c >= '0');
	return x;
}
const int maxn = 50005;
vector<int>g1[maxn], g2[maxn];
int leaf, n, col;
int cc[5], f[maxn][5];

ll ans, nans;
//edge - node = 1
int select2(int x){
	// assert(x >= 0);
	return x * (x - 1) / 2;
}
void solve(int x, int fa){
	// if(x <= leaf)return;
	int ls = 0, rs = 0;
	for(int v : g2[x]){
		if(v == fa)continue;
		solve(v, x);
		f[x][1] += f[v][1];
		f[x][2] += f[v][2];
		f[x][3] += f[v][3];
		if(ls)rs = v; else ls = v;
	}
	if(!ls || !rs)return;
	// assert((ls == 0 && rs == 0) || (ls != 0 && rs != 0));
	if(fa){
		int f1 = cc[1] - f[x][1], f2 = cc[2] - f[x][2], f3 = cc[3] - f[x][3];		
		nans = nans - select2(f1) * (0ll + select2(f[ls][2]) + select2(f[ls][3]) + select2(f[rs][2]) + select2(f[rs][3]));
		nans = nans - select2(f2) * (0ll + select2(f[ls][1]) + select2(f[ls][3]) + select2(f[rs][1]) + select2(f[rs][3]));
		nans = nans - select2(f3) * (0ll + select2(f[ls][1]) + select2(f[ls][2]) + select2(f[rs][1]) + select2(f[rs][2]));
		// printf("tree 2 node : %d del node now nans = %lld\n", x, nans);
	}
	nans = nans - select2(f[ls][1]) * (0ll + select2(f[rs][2]) + select2(f[rs][3]));
	nans = nans - select2(f[ls][2]) * (0ll + select2(f[rs][1]) + select2(f[rs][3]));
	nans = nans - select2(f[ls][3]) * (0ll + select2(f[rs][1]) + select2(f[rs][2]));
	// printf("tree 2 node : %d del node now nans = %lld\n", x, nans);

	nans = nans + select2(f[ls][1]) * (0ll + select2(cc[2] - f[ls][2]) + select2(cc[3] - f[ls][3]));
	nans = nans + select2(f[ls][2]) * (0ll + select2(cc[1] - f[ls][1]) + select2(cc[3] - f[ls][3]));
	nans = nans + select2(f[ls][3]) * (0ll + select2(cc[1] - f[ls][1]) + select2(cc[2] - f[ls][2]));
	// printf("tree 2 node : %d del edge - > %d now nans = %lld\n", x, ls,  nans);
	
	nans = nans + select2(f[rs][1]) * (0ll + select2(cc[2] - f[rs][2]) + select2(cc[3] - f[rs][3]));
	nans = nans + select2(f[rs][2]) * (0ll + select2(cc[1] - f[rs][1]) + select2(cc[3] - f[rs][3]));
	nans = nans + select2(f[rs][3]) * (0ll + select2(cc[1] - f[rs][1]) + select2(cc[2] - f[rs][2]));
	// printf("%d %d %d %d %d %d\n",f[rs][1], f[rs][2], f[rs][3], cc[1], cc[2], cc[3]);
	// printf("tree 2 node : %d del edge - > %d now nans = %lld\n", x, rs, nans);

}

void upd(int x, int fa){
	for(int i = 1; i <= 4; ++i)f[x][i] = 0;
	// printf("upd : %d %d %d\n", x, fa, col);
	if(x <= leaf){ ++f[x][col]; ++cc[col]; return; }
	for(int v : g1[x]) if(v != fa)upd(v, x);
}
void del(int x, int fa){
	col = 0; cc[1] = cc[2] = cc[3] = 0;
	for(int v : g1[x]){
		for(int i = 1; i <= 4; ++i)f[x][i] = 0;
		++col, upd(v, x);
	}	
	nans = 0; solve(1, 0); ans = ans - nans; 
	// printf("del node : %d now nans = %lld\n\n",x , nans);
	for(int v : g1[x]){
		if(v == fa)continue;
		cc[1] = cc[2] = cc[3] = 0;
		col = 1; upd(v, x); col = 2; upd(x, v);
		nans = 0; solve(1, 0); ans = ans + nans;
		// printf("del edge : %d < - > %d now nans = %lld\n\n",x, v, nans);
	}
	for(int v : g1[x])if(v != fa)del(v, x);
}
int main(){
	freopen("b.in","r",stdin);
	freopen("b.out","w",stdout);
	leaf = read(); n = leaf + leaf - 2;
	for(int i = 1; i < n; ++i){
		int u = read(), v = read();
		g1[u].push_back(v), g1[v].push_back(u);
	}
	for(int i = 1; i < n; ++i){
		int u = read(), v = read();
		g2[u].push_back(v), g2[v].push_back(u);	
	}
	del(n, 0);
	ans = 1ll * leaf * (leaf - 1) * (leaf - 2) * (leaf - 3) / 12 - ans - ans;
	printf("%lld\n",ans);
	return 0;
}

C. T3

标签:层省,rs,int,cc,nans,include,select2
来源: https://www.cnblogs.com/Chencgy/p/16597459.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有