ICode9

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

题解 party?

2021-08-20 07:32:46  阅读:236  来源: 互联网

标签:int 题解 top long mson ans party define


传送门

挺遗憾的一个题
考场上想到的思路是题解的退化版,可以有71pts(赛时以为只有20pts),但因为这一场的策略原因没有打……

首先发现颜色种类数很少,可以直接bitset上树剖维护,炸不了空间
所以可以先bitset上树剖处理出每个人到lca经过的颜色集合
然后问题可以转化为给定 \(c\) 个集合,求「让所有集合中剩余元素互不相同且剩余个数相同的最大保留个数」
这个考场上没什么思路,想直接用网络流二分搞,图很好建

至于正解,前面都是一样的,不同之处在于这里的网络流
这里直接建图肯定是源点向每个人建流量为 \(mid\) 的边
但考虑将每个人直接拆成 \(mid\) 个点,问题就转化成了求二分图完美匹配

  • 霍尔定理:一个二分图 \(g\) 存在完美匹配,当且仅当 \(x\) 中的任意 \(k\) 个点都至少与 \(y\) 中的 \(k\) 个点相邻
  • 霍尔定理推论:见这里,貌似很有用的样子但我没康懂

于是对于到这个题上,发现本质不同的左部点很少,而本质相同的左部点对应的相邻点集合是相同的
又有

\[| s | *ans \leqslant | to_s | \]

移个项,

\[ans = min\{\frac{|to_s|}{|s|}\} \]

Code:

#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 300010
#define ll long long 
//#define int long long 

char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
	int ans=0, f=1; char c=getchar();
	while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
	while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
	return ans*f;
}

int n, m, q;
int head[N], size, val[N], id[N], rk[N], top[N], siz[N], msiz[N], mson[N], fa[N], tot, dep[N];
bitset<1001> to[6], rec;
struct edge{int to, next;}e[N<<1];
inline void add(int s, int t) {e[++size].to=t; e[size].next=head[s]; head[s]=size;}
int tl[N<<2], tr[N<<2]; bitset<1001> dat[N<<2];
#define tl(p) tl[p]
#define tr(p) tr[p]
#define dat(p) dat[p]
#define pushup(p) dat(p)=dat(p<<1)|dat(p<<1|1)
void build(int p, int l, int r) {
	tl(p)=l; tr(p)=r;
	if (l==r) {dat[p][val[rk[l]]]=1; return ;}
	int mid=(l+r)>>1;
	build(p<<1, l, mid);
	build(p<<1|1, mid+1, r);
	pushup(p);
}
void query(int p, int l, int r, bitset<1001>& ans) {
	//cout<<"query1 "<<p<<' '<<l<<' '<<r<<endl;
	if (l<=tl(p) && r>=tr(p)) {ans|=dat(p); return ;}
	int mid=(tl(p)+tr(p))>>1;
	if (l<=mid) query(p<<1, l, r, ans);
	if (r>mid) query(p<<1|1, l, r, ans);
}

void dfs1(int u) {
	siz[u]=1;
	for (int i=head[u],v; ~i; i=e[i].next) {
		v = e[i].to;
		dep[v]=dep[u]+1, fa[v]=u, dfs1(v);
		siz[u]+=siz[v];
		if (siz[v]>msiz[u]) msiz[u]=siz[v], mson[u]=v;
	}
}
void dfs2(int u, int t) {
	top[u]=t;
	id[u]=++tot;
	rk[tot]=u;
	if (!mson[u]) return ;
	dfs2(mson[u], t);
	for (int i=head[u],v; ~i; i=e[i].next) {
		v = e[i].to;
		if (v!=mson[u]) dfs2(v, v);
	}
}
int lca(int a, int b) {
	while (top[a]!=top[b]) {
		if (dep[top[a]]<dep[top[b]]) swap(a, b);
		a=fa[top[a]];
	}
	if (dep[a]>dep[b]) swap(a, b);
	return a;
}
void query(int a, int b, bitset<1001>& ans) {
	//cout<<"query2 "<<a<<' '<<b<<endl;
	while (top[a]!=top[b]) {
		if (dep[top[a]]<dep[top[b]]) swap(a, b);
		query(1, id[top[a]], id[a], ans);
		a=fa[top[a]];
	}
	if (dep[a]>dep[b]) swap(a, b);
	query(1, id[a], id[b], ans);
}

signed main()
{
	memset(head, -1, sizeof(head));
	n=read(); m=read(); q=read();
	for (int i=2; i<=n; ++i) add(read(), i);
	for (int i=1; i<=n; ++i) val[i]=read();
	dep[1]=1; dfs1(1); dfs2(1, 1); build(1, 1, n);
	int t[10];
	for (int i=1,c,g; i<=q; ++i) {
		c=read();
		for (int j=1; j<=c; ++j) t[j]=read();
		g=t[1];
		for (int j=2; j<=c&&g!=1; ++j) g=lca(g, t[j]);
		//cout<<"lca: "<<g<<endl;
		for (int j=1; j<=c; ++j) {to[j].reset(); query(g, t[j], to[j]);}
		//cout<<1<<endl;
		int lim=1<<c, ans=INF;
		for (int s=1,s2,cnt; s<lim; ++s) {
			s2=s; cnt=0; rec.reset();
			do {s2&=s2-1; ++cnt;} while (s2) ;
			for (int j=0; j<c; ++j) if (s&(1<<j)) 
				rec|=to[j+1];
			//cout<<"upd: "<<rec.count()<<' '<<cnt<<endl;
			ans = min(ans, int(rec.count())/cnt);
		}
		printf("%d\n", ans*c);
	}
	
	return 0;
}

标签:int,题解,top,long,mson,ans,party,define
来源: https://www.cnblogs.com/narration/p/15164785.html

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

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

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

ICode9版权所有