首页 > 其他分享 >【题解】[ABC312G] Avoid Straight Line(容斥,树上统计,dfs)

【题解】[ABC312G] Avoid Straight Line(容斥,树上统计,dfs)

时间:2023-07-30 13:45:15浏览次数:35  
标签:le int 题解 Avoid 路径 容斥 三元组 树上 节点

【题解】[ABC312G] Avoid Straight Line

题目链接

[ABC312G] Avoid Straight Line

题意概述

给定一棵 \(n\) 个节点的树,第 \(i\) 条边连接节点 \(a_i\) 和 \(b_i\),要求找到满足以下条件的三元整数组 \((i,j,k)\) 的数量:

  • \(1\le i<j<k\le n\);
  • 对于树上任意一条简单路径,都不同时经过 \(i,j,k\)。

数据范围

  • \(1 \le n \le 2\times 10^5\)
  • \(1\le a_i,b_i \le n\)

思路分析

题目要求对于树上任意一条简单路径都不同时经过 \(i,j,k\),这个条件直接思考不容易想出来有什么处理的办法,考虑正难则反,我们可以先求出树上至少有一条路径同时经过 \(i,j,k\) 时满足条件的三元组 \((i,j,k)\) 的数量,然后再容斥。

即,问题可以转化为:

树上所有满足 \(1\le i<j< k\le n\) 的三元组 \((i,j,k)\) 的数量减去树上至少有一条路径同时经过 \(i,j,k\) 时,满足条件的三元组 \((i,j,k)\) 的数量

树上所有满足 \(1\le i <j<k \le n\) 的三元组 \((i,j,k)\) 的数量实际上就是在 \(1-n\) 的所有数中找到三个数 \((i,j,k)\) 使得 \(1 \le i<j<k \le n\) 的数量,也就是 \(\mathrm{C_n^3}=\dfrac{n\times (n-1)\times (n-2)}{6}\)。


现在问题就只剩下:树上至少有一条路径同时经过 \(i,j,k\) 时满足条件的三元组 \((i,j,k)\) 的数量怎么求。

有一条路径同时经过 \(i,j,k\) 实际上就相当于是 \(i\) 在 \(j\) 到 \(k\) 的路径上,或 \(j\) 在 \(i\) 到 \(k\) 的路径上,或 \(k\) 在 \(i\) 到 \(j\) 的路径上。

这就给了我们一个思路:我们首先可以钦定一个中间节点 \(u\),即对于每一个点 \(u\),其中 \(1 \le u \le n\),满足有多少个不同于 \(u\) 的无序点对 \((v,w)\) 使得 \(u\) 在点 \(v\) 到 \(w\) 的路径上。这也就是当 \(u\) 作为中间节点时符合条件的三元组的数量。

那么树上所有的点作为中间节点时的答案之和,就是树上至少有一条路径同时经过 \(i,j,k\) 时满足条件的三元组 \((i,j,k)\) 的数量。

现在考虑怎么求当固定点 \(u\) 作为中间节点时,有多少个不同于 \(u\) 的无序点对 \((v,w)\) 使得 \(u\) 在 \(v\) 到 \(w\) 的路径上。

考虑当 \(u\) 作为整棵树的根时,显然要使得 \(u\) 成为中间节点,那么当它的一个子树内的节点 \(t\) 作为 \(v\) 时,与 \(t\) 在同一个子树内的节点一定不能作为 \(w\),只有与它不在同一个子树内非 \(u\) 的节点才有可能成为 \(w\),也就是说其它子树内任意一个节点都可以作为 \(w\)。

也就是说对于 \(u\) 的一个子树的根 \(t\),该子树的点作为 \(v\) 的方案数是 \(sz_t\times (n-sz_t-1)\),由于是无序点对(即 \((v,w)\) 和 \((w,v)\) 算同一个点对,为了防止计算重复,那么我们需要在枚举 \(u\) 的儿子时,每次减去当前已经被算过的点的个数,即我们可以定义一个 \(now\),初始化 \(now=n-1\),每次计算完一个子树 \(t\) 的答案,就让 \(now\) 减去 \(sz_t\)(因为这个子树内的点与后面子树的点的组合成为点对算过答案了,之后就没有必要再计算了),那么当前这个子树 \(t\) 的答案 \(ans_t=sz_t\times now\)(具体详见下面的代码)。那么 \(u\) 作为中间节点的点答案就是它所有的儿子的答案之和,即 \(\sum \limits_{t\in son_u} ans_t\)。

那么对于最后满足条件的三元组的数量 \(ans\),我们只需要从 \(1\) 开始 dfs 一遍,跑出所有点作为中间节点的答案然后加起来就可以了。

最终的答案就是 \(\mathrm{C_n^3}-ans\)。

代码实现

//G
//The Way to Terminal Station…
#include<cstdio>
#include<iostream>
#include<cstring>
#define int long long
using namespace std;
const int maxn=2e5+10;
int sz[maxn];
int ans,n;

basic_string<int>edge[maxn];

inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}

void dfs(int x,int fa)
{
	int ret=0;
	for(int y:edge[x])
	{
		if(y==fa)continue;
		dfs(y,x);
		sz[x]+=sz[y];
	}
	sz[x]++;
	int now=n-1;
	for(int y:edge[x])
	{
		if(y==fa)continue;
		now-=sz[y];
		ret+=sz[y]*now;
	}
	if(edge[x].size()>1)ans+=ret;
	return ;
}

signed main()
{
	n=read();
	for(int i=1;i<n;i++)
	{
		int a,b;
		a=read();b=read();
		edge[a]+=b;
		edge[b]+=a;
	}
	int tot=n*(n-1)*(n-2)/6;
	dfs(1,0);
	cout<<tot-ans<<'\n';
	return 0;
}

标签:le,int,题解,Avoid,路径,容斥,三元组,树上,节点
From: https://www.cnblogs.com/xrkforces/p/ABC312G.html

相关文章

  • CF1855B Longest Divisors Interval 题解
    题意:给定一个数\(n\),求一个连续区间\([l,r]\)使得\(n\)是区间内每个数的倍数,最大化这个区间的长度(多组数据)。思路:逆向思考一波,(如果一个数\(x\)不是\(n\)的因数,那么\(x\)的倍数不能在区间内。举个例子,比如$n$是13,3不是13的因数,\(3,6,9,12\)也就不可能出现......
  • Codeforces Round 889 (Div. 1) 题解
    A1.Dual(EasyVersion)https://codeforces.com/contest/1854/problem/A1题意给定一个长度为\(n\)的序列\(a_1,a_2,\dots,a_n\),你可以做以下操作:选定两个下标\(i,j(1\leqi,j\leqn)\),\(i,j\)可以相同,然后\(a_i\leftarrowa_{i}+a_j\)。要求构造一种操作......
  • HDU 1312 Red and Black 题解
    //注意边界判断,调了好久#include<iostream>#include<queue>usingnamespacestd;#definecheck(x,y)(x<wx&&x>=0&&y<hy&&y>=0)structnode{intx,y;};charroom[23][23];intn,m,wx,hy,num;intdir[4][2]={......
  • AvoidStraightLine
    ABC312G:AvoidStraightLine为DistanceSums2的简单扩展,做法完全一致。题解:https://blog.csdn.net/weixin_52536621/article/details/127039502)(树形那一栏)考虑对于一个三元组,要求解不在一条简单路径上的三点,发现不好做,那我们可以求在一条简单路径上的三点,然后根据组合数\(C_n......
  • Xum题解
    Xum洛谷传送门题意:简化来说就是给你一个奇数\(x\),而你只能使用\(+\)或\(\bigoplus\),让你构造出一个包含\(1\)的数集。Analysis:首先为了得到\(1\),我们一般有两种思路,第一种是构造出\(n\)与\(n+1\)这种“出解情况”,这种思路考场寄掉了,先咕。那么来说说正解思路......
  • Sctf2023 Re 部分题解
    re是谁不复习计网和数据库写reSyclang给出两个文件一个是ir一个是编译器直接看ir即可拿vscode正则匹配替换relpace:(var\d+)\(@exp.([XLRXkey]+)(\[\d\])\)$1.$2$3#(\d+)$1<\+\d+>""(var\d+)\(@exp(.key\[\d+\])\)$1$2LABEL""GOTOgoto#!te......
  • 暑期竞赛配训 Day 1,本蒟蒻的第一篇题解qwq!
    洛谷P8725[蓝桥杯2020省AB3]画中漂流:-[1]读题:在梦境中,你踏上了一只木䇝,在江上漂流。根据对当地的了解,你知道在你下游D米处有一个峡谷,如果你向下游前进大于等于D米则必死无疑。现在你打响了急救电话,T秒后救援队会到达并将你救上岸。水流速度是1m/s,你现在有M点体力......
  • P9387 [THUPC 2023 决赛] 巧克力 题解
    这篇题解会只讲怎么dp,所以我们这里跳过博弈论的部分。Let'srephrasetheproblemstatementasfollows:给定\(n,m\),设\(x=1\oplus2\oplus\cdots\oplusn\oplusm\)。求有多少个有序三元组\((a,b,c)\)满足:\(a+b+c\len\)或\(a+b+c=m\)(如果都满足需要算两遍)。\((a+b......
  • Educational Codeforces Round 152 (Rated for Div. 2) 题解
    \(6\)题做出来\(3\)题,这一次的D题没能复刻上一次Round888Div.3最后几分钟AC的奇迹A.MorningSandwich大水题,5min时间4min都在翻译题面直接拿\(b\)和\(c+h\)进行比较分类讨论即可单次操作时间复杂度\(O(1)\)B.Monsters首先有一个特别显然、复杂度特别高的......
  • luogu P4069 [SDOI2016] 游戏 题解【李超树+树剖】
    目录题目描述解题思路code题目描述P4069[SDOI2016]游戏一棵树,树上有\(n\)个节点,最初每个节点上有\(1\)个数字:\(123456789123456789\)。有两种操作:\(\centerdot\)选择\(s,t\)两个节点,将路径上的每一个点都变多(\(1\)个变\(2\)个)数字:\(a\timesdis+b\),其中\(dis\)表示该节点......