首页 > 其他分享 >【大联盟】20230626 集查并(dsu) 题解 AT_toyota2023spring_final_g 【Git Gud】

【大联盟】20230626 集查并(dsu) 题解 AT_toyota2023spring_final_g 【Git Gud】

时间:2023-07-22 11:13:25浏览次数:42  
标签:Git tx Val Gud int 题解 ll Siz void

【大联盟】20230626 集查并(dsu) 题解 AT_toyota2023spring_final_g 【Git Gud】

zyx /bx

题目描述

here

题解

由于这场出了 T2、验了 T3(顺序是反的),所以赛时一直在想这个题,不过很遗憾不会。

相当有意思的题。

考虑合并两个点 \(x,y\) 时,对以后产生的贡献为 \(\max\{f_x,f_y\}\),\(f_x\) 为 \(x\) 点当前剩下的度数,则合并出来的新点当前剩下的度数为 \(f_{new}=f_x+f_y-2\)。

这并不是一个好维护的形式,我们考虑初始时让每个点 \(f'(x)=f(x)-2\),这样,每次合并就可以直接 \(f'(x)=f'(x)+f'(y)\),每次算贡献的时候就是 \(\max\{f_x,f_y\}+2\),感觉非常酷!

然后还有个结论:我们 merge 的顺序是按照一棵有根树来操作的,先操作根,再操作下面的点。有了这个加的限制就可以根据 典中典 Color a Tree 的做法来做了。

形式大概是第 \(i\) 次操作 \(x\),贡献为 \(if_x\)。

证明大概就是调整法来证。

代码

记录

#include <bits/stdc++.h>
#define SZ(x) (int) x.size() - 1
#define all(x) x.begin(), x.end()
#define ms(x, y) memset(x, y, sizeof x)
#define F(i, x, y) for (int i = (x); i <= (y); i++)
#define DF(i, x, y) for (int i = (x); i >= (y); i--)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
template <typename T> void chkmax(T& x, T y) { x = max(x, y); }
template <typename T> void chkmin(T& x, T y) { x = min(x, y); }
template <typename T> void read(T &x) {
	x = 0; int f = 1; char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
const int N = 2010;
int n, fa[N], far[N];
ll mx;
vector <int> v[N];
void dfs(int x, int fa) {
	far[x] = fa;
	for (int i: v[x])
		if (i != fa) dfs(i, x);
}
struct Node {
	int x, y, id;
	inline friend bool operator < (const Node &x, const Node &y) {
		if ((ll) x.x * y.y == (ll) y.x * x.y) return (x.id == y.id) ? x.y < y.y : x.id < y.id;
		return (ll) x.x * y.y < (ll) y.x * x.y;
	}
	inline friend bool operator == (const Node &x, const Node &y) {
		return x.x == y.x && x.y == y.y && x.id == y.id;
	}
} t[N];
int find(int x) {
	return fa[x] == x ? x : fa[x] = find(fa[x]);
}
template <typename _Tp> class heap {
    priority_queue<_Tp> _Val, _Del; bool _Op; size_t _Siz;
    void flush() {
        while(!_Del.empty() && !_Val.empty() && _Del.top() == _Val.top()) _Val.pop(), _Del.pop(); _Op = 0;
    }
    public:
    heap() : _Op(0), _Siz(0) {}
    size_t size() {return _Siz;}
    void push(const _Tp &x) {_Siz++; _Val.push(x);}
    _Tp top() {
        assert(_Siz); if(_Op) flush(); assert(!_Val.empty()); return _Val.top();
    }
    void pop() {
        assert(_Siz); _Siz--;
        if(_Op) flush(); _Op = (!_Del.empty());
        assert(!_Val.empty()); _Val.pop();
    }
    bool empty() {return _Siz == 0;}
    void erase(const _Tp &x) {
        assert(_Siz); _Siz--;
        if(_Op) flush(); assert(!_Val.empty());
        if(x == _Val.top()) {
            _Val.pop(); _Op = 1; return;
        }
        assert(x < _Val.top()); _Del.push(x);
    }
    void clear() {
        _Op = _Siz = 0; priority_queue<_Tp> _Tx, _Ty;
        swap(_Val, _Tx), swap(_Del, _Ty);
    }
};
signed main() {
// 	freopen("dsu.in", "r", stdin);
// 	freopen("dsu.out", "w", stdout);
	read(n);
	F(i, 2, n) {
		int x, y; read(x), read(y); x++, y++;
		v[x].push_back(y);
		v[y].push_back(x);
	}
	F(i, 1, n) {
		dfs(i, 0);
		heap <Node> q;
		ll ans = 3 * (n - 1);
		F(j, 1, n) {
			fa[j] = j;
			t[j] = {(int) v[j].size() - 2, 1, j};
			if (j != i) q.push(t[j]);
			ans += (ll) (n - 1) * ((int) v[j].size() - 2);
		}
		int s = 0;
		while (q.size()) {
			int x = q.top().id;
			q.pop();
			int tx = find(far[x]);
			if (tx != i) q.erase(t[tx]);
			ans -= (ll) t[tx].y * t[x].x;
			fa[x] = tx;
			t[tx].x += t[x].x;
			t[tx].y += t[x].y;
			if (tx != i) q.push(t[tx]);
		} chkmax(mx, ans);
	} cout << mx;
	return 0;
}

标签:Git,tx,Val,Gud,int,题解,ll,Siz,void
From: https://www.cnblogs.com/zhaohaikun/p/17573009.html

相关文章

  • JOI2013 JOIOI の塔 (Tower of JOIOI)题解
    Description给定一个由J、O、I组成的字符串,求最多能拆分成多少JOI或IOI。对于所有数据,\(1\leq\vertS\vert\leq10^6\)。Solution先处理出\(\text{pre}_i\)为前缀J和I的数量,即能组成多少个头部。然后倒着做,维护当前拼出的I、OI和最终成品的数量。遇到J、O就......
  • 【大联盟】20230703 T2 开心的序列(sequence) 题解 AT_agc049_f 【[AGC049F] Happy Sequ
    zak/bx恐怖zak将这题加强,出到模拟赛。直接把\(A_i,B_i\le10^5,C_i\le5\)变成了\(A_i,B_i,C_i\le10^9\)。非常恐怖。题目描述点击膜拜zhoukangyang。题解重新再理解一遍。我们维护\(p(x)=\sum_i|a_i-x|+|b_i-x|\),那么就相当于要求\(\forallx,p(x)\le0\),也就......
  • 同一台电脑配置公司git和个人git
    https://www.cnblogs.com/hezhi/p/10317642.html照着这篇文章的第二章做就行,亲测有效。建议有条件的情况下专门配一台公司电脑,避免泄露公司代码。......
  • Luogu P4552 [Poetize6] IncDec Sequence 更好的题解
    原题链接第一步对于学过差分的人应该不难想定义差分数组$dis\quads.t.\quaddis[i]=a[i]-a[i-1]$那么不难发现问题一只要让\(dis[2]...dis[n]\)中全部为\(0\)即可区间\([l,r]\)加一操作在差分数组中意味着\(dis[l]=dis[l]+1,dis[r+1]=dis[r+1]-1\)即在差分数组......
  • 在vscode中配置git
    1.配置VsCode的Git地址1.1.打开“文件”-“首选项”-“设置” 搜索git.path  打开setting.json1.2.添加“git.path”:“Git实际安装地址”VsCode中git路径的设置(window系统)---参考文章https://code84.com/767977.html2.在vscode中,默认提交到master分支2.1.有文件更改......
  • [Joplin] git实现Joplin多PC端加密文件同步
    git实现Joplin多PC端加密文件同步场景一些笔记虽然不是什么重要的东西,但是需要加密一下同时也要在不同的PC端进行编辑(上班+下班)方案通过Joplin加密文件内容,将加密文件同步到本地Filesystem再通过git上传到代码托管平台步骤前提:已有项目仓库,会用......
  • 2023 暑假集训模拟赛题解
    目录CSP模拟1CSP模拟2FSYOCSP模拟1来自学长的馈赠2.CSP模拟2F考虑\(x\)只能在\(a_1\oplusb_i\)里选,那么分别代入暴力检验即可.时间复杂度\(\tilde\Theta(n^2)\),可以通过.S考虑交换同色的部分一定不优,所以同色字符的相对位置一定是不变的.那么操作序列......
  • 幽灵乐团 题解
    幽灵乐团题目大意\(T\)组数据,每组数据给定\(A,B,C\),求:\[\prod_{i=1}^A\prod_{j=1}^B\prod_{k=1}^C\Big(\frac{\text{lcm}(i,j)}{\gcd(i,k)}\Big)^{f(type)}\bmodp\]其中,\(type\in\{0,1,2\}\),\(f(0)=1,f(1)=i\timesj\timesk,f(2)=\gcd(i,j,k)\)。思路分析神经污......
  • gitlab的CICD中自定义钉钉发送内容(通过sh脚本发送测试结果)
    背景:这里报告是allure,提取数据可以用data/categories.csv这个文件思路跟上一篇的python是一样的,这里就简单贴下代码 这里需要注意的是json的转义,message变量需要用双引号括起来。CICD中配置如下 ......
  • 【问题解决】docker版本v23.0后,构建Dockerfile中FROM私库镜像报错构建失败
    问题情况Docker版本在v23.0以后,只要Dockerfile中FROM的私库镜像不存在本地,就会报错:#我本地是v24.0.2版本Docker[root@localhostipd]#dockerbuild.-tharbor.xxx.com.cn/test/bap:2.7.1[+]Building0.6s(3/3)FINISHED......