首页 > 其他分享 >P10064 [SNOI2024] 公交线路 题解

P10064 [SNOI2024] 公交线路 题解

时间:2024-05-04 11:22:17浏览次数:34  
标签:md power sz 题解 sum P10064 ans c1 SNOI2024

弱化版:CF1827E Bus Routes

对于 \(n=2\) 的情况可以判掉,剩下的情况取一个度数大于一的点作为根。

首先发现如果叶子间满足条件,那么整棵树也满足条件。考虑叶子间什么时候满足条件,记点 \(x\) 通过最多一条路径可以到达的所有点的集合为 \(S_x\),则需满足 \(\forall x,y\in \mathbf{leaf},S_x\cap S_y\ne \emptyset\)。

又因为这是一颗树,可以推得 \(\bigcap_{x\in \mathbf{leaf}}S_x\ne \emptyset\),且这个交在原树中一定是一个连通块。考虑经典的点减边容斥,答案即为钦定经过每一个点的方案数的和减去钦定经过每一条边的方案数的和。

先考虑怎么计算钦定经过每一个点的方案数的和。放到原树上考虑,先钦定在它子树外的所有叶子节点都满足条件,然后对于它的子树可以容斥计算。

因为它的一个儿子的子树中的叶子节点都是一样的,所以对于每个儿子只需要知道钦定了多少个不合法的叶子节点,背包合并即可,最后再乘上一些系数。

对于钦定经过边的情况类似,也是先钦定子树外的叶子节点都满足条件(这是为了保证背包这部分的总时间复杂度是 \(\mathcal O(n^2)\)),然后子树内再做一遍容斥。

然后就做完了,有亿些细节,时间复杂度 \(\mathcal O(n^2)\)。

参考代码:

#include<bits/stdc++.h>
#define ll long long
#define mxn 3003
#define md 998244353
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define rept(i,a,b) for(int i=a;i<b;++i)
using namespace std;
struct node{
	int x,y;
}e[mxn];
int n,tot,sz[mxn],c1[mxn],c[mxn][mxn];
vector<int>g[mxn];
ll ans,d[mxn],dp[mxn][mxn];
ll power(ll x,int y){
	ll ans=1;
	for(;y;y>>=1){
		if(y&1)ans=ans*x%md;
		x=x*x%md;
	}
	return ans;
}
void dfs(int x,int fa){
	if(g[x].size()==1){
		sz[x]=c1[x]=1;
		return;
	}
	dp[x][0]=1,sz[x]=1;
	int cnt=0;
	for(int i:g[x])if(i!=fa){
		dfs(i,x);
		cnt+=sz[i]*(sz[i]-1)/2;
		rep(j,0,c1[x])d[j]=dp[x][j],dp[x][j]=0;
		rep(j,0,c1[x]){
			rep(k,0,c1[i]){
				dp[x][j+k]=(dp[x][j+k]+d[j]*c[c1[i]][k]%md*power(2,(sz[i]-k)*(sz[x]-j)))%md;
			}
		}
		sz[x]+=sz[i],c1[x]+=c1[i];
	}
	cnt+=(n-sz[x])*(n-sz[x]-1)/2;
	ll sum=0;
	rep(j,0,c1[x])sum=(sum+(j&1?-1:1)*dp[x][j]*power(2,(sz[x]-j)*(n-sz[x]-(tot-c1[x])))%md*power(power(2,sz[x]-j)-1,tot-c1[x]))%md;
	ans=(ans+sum*power(2,cnt))%md;
	if(fa){
		sum=0;
		rep(j,0,c1[x])sum=(sum+(j&1?-1:1)*c[c1[x]][j]*power(2,(sz[x]-j)*(n-sz[x]-(tot-c1[x])))%md*power(power(2,sz[x]-j)-1,tot-c1[x]))%md;
		ans=(ans-sum*power(2,(n-sz[x])*(n-sz[x]-1)/2+sz[x]*(sz[x]-1)/2))%md;
	}
}
signed main(){
	scanf("%d",&n);
	c[0][0]=1;
	rep(i,1,n){
		c[i][0]=1;
		rep(j,1,i)c[i][j]=(c[i-1][j-1]+c[i-1][j])%md;
	}
	for(int i=1,x,y;i<n;++i){
		scanf("%d%d",&x,&y);
		g[x].pb(y),g[y].pb(x);
		e[i]={x,y};
	}
	if(n==2){
		puts("1");
		return 0;
	}
	rep(i,1,n)if(g[i].size()==1)tot++;
	int rt=1;
	while(g[rt].size()==1)rt++;
	dfs(rt,0);
	cout<<(ans+md)%md;
	return 0;
}

标签:md,power,sz,题解,sum,P10064,ans,c1,SNOI2024
From: https://www.cnblogs.com/zifanoi/p/18172124

相关文章

  • [国家集训队] 矩阵乘法 题解
    发现实际上就是二维静态区间最大值,可以用整体二分维护。时间复杂度\(O((q+n^2)\log\max(a_{i,j})\logn^2)\)。#include<bits/stdc++.h>#definelllonglongusingnamespacestd;constintW=310005;constintQ=6e4+5;intn,q,w,ans[Q];intc[505][505],m;voidadd(i......
  • 题解【[ABC147F] Sum Difference】
    题目链接下为口胡题解:入手方向推导:直接考虑题目所给式子显然困难:\[w(S)=\sum_{i\inS}A_i-\sum_{i\notinS}A_i\]因为两个式子虽然相关但是都在变化,不妨转化为:\[w(S)=2\times\sum_{i\inS}A_i-\sum_{i=1}^nA_i\]这样只用求出有多少个不同的\(\sum_{i\inS}A_i\)。由于......
  • CF1968E.Cells Arrangement-构造(给个和题解不同的做法)
    link:https://codeforces.com/problemset/problem/1968/E题意:需要构造一个\(n\timesn\)的棋盘,在上面放\(n\)枚棋子,设集合\(\mathcal{H}\)表示两两之间曼哈顿距离构成的集合,要让\(|\mathcal{H}|\)最大。给出放棋子的方案。首先说说题解的做法…考虑把距离为奇数和偶数的......
  • 题解:CF1926G
    题目传送门思路发现权值为C的点可以选择看做是权值为S或为P的点,所以问题转换为怎么给C点赋值可以使答案最小,考虑树形dp。\(f_{i,0/i,1}\)表示\(i\)点赋值为S或P时最少要删除几条边。但如果当前点权值不为C的话,那显然他的父亲节点应该选择和他权值相同的点才......
  • 题解:AT_abc298_h [ABC298Ex] Sum of Min of Length
    分析模拟赛签到题。考虑分讨。分两种情况:\(L=R\)。\(L\neR\)。对于第\(1\)种情况,用换根DP求一个\(i\)为根时所有点的深度和就行。对于第\(2\)种情况,钦定$dep_R\gedep_L$。很显然,\(R\)为根的子树中所有点都是离\(R\)更近。假设在\(L\)到\(R\)的路径......
  • 题解【[ABC077D] Small Multiple】
    题目链接题意简述:给定正整数\(K\),求数位之和最小的\(K\)的倍数的数位和。错误方向:\(K\)的倍数一定满足\(K\timesS\),根据\(K\)的特征构造出合适的\(S\)。正确方向考虑直接构造出K的倍数,由于从1开始可以通过×10和+1构造出所有数字,并且在此......
  • 【题解】P4711 「化学」相对分子质量
    Problem给定一个长度为\(L\)的化学式,求出此化学式的相对分子质量。例:十二水合硫酸铝钾(明矾)\(KAl(SO_4)_2\cdot12H_2O\).输入格式形为:KAl(SO_{4})_{2}~12H_{2}OSolve清新小模拟。定义一下“结账”这个概念,分为三种:原子结账,即为当单独的一个(一坨)原子计算完成后,计入所属......
  • [题解]ABC337E Bad Juice
    ABC337EBadJuice一开始的想法如下:就是利用二分法,对于一个区间\([l,r]\),分成\([l,mid-1],[mid,r-1]\)两部分,各找两个朋友喝,右边还空出一个\(r\),如果前面两个朋友都没中毒,那说明\(r\)这瓶有毒。但仔细一想,我们发现\([1,n)\)的瓶子中任意一个我们分出的区间\([l,r]\),都用去了\(......
  • 题解:CF607E Cross Sum
    Problem给定\(N\)条不平行的直线\(y=\frac{k_i}{1000}x+\frac{b_i}{1000}\),\(N\)条直线总共会有\(\frac{N(N-1)}{2}\)个交点(包含在同一个位置的点,即相同位置算不同的点),找出距离原点前\(K\)近的交点的距离和。$2\leN\le5\times10^4$,\(1\leK\le\frac{N(N-1)}{2}\)......
  • P6123 [NEERC2016] Hard Refactoring 题解
    本题说白了,就是一道big模拟!!!题意不再赘述,我们直接看思路。这里作者借鉴了某差分思想:末尾加空格,用于判断最后一个条件;若只有\(\le\),对给出的数字和数组第一个进行标记。标记的时候要+32769,因为数组中不存在负数下标,以免越界;若只有\(\ge\),就标记给出的数字和数组最后......