【PKUSC2019】線弦圖【計數】【樹形DP】【分治FFT】

Description

定義線圖為把無向圖的邊變成點,新圖中點與點之間右邊當且僅當它們對應的邊在原圖中有公共點,這樣得到的圖。
定義弦圖為不存在一個長度大于3的純環,純環的定義是在環上任取兩個不相鄰的點,它們之間都沒有邊,也就是不存在沒有弦的環的無向圖。

現在給出一棵n個點的樹,你可以在上面添加任意多條邊(不能重邊),要求得到的圖的線圖是弦圖,求加邊的方案數。
n<=200000

Solution

畫圖可以發現,一個無向圖的線圖是弦圖的充要條件就是不存在長度大于3的環(不一定是純環)

也就是說,我們加邊只能加成三角形,并且加的邊還不能交叉。
轉化后的題意等價于將樹上的邊分成若干個集合,每個集合要么是單獨一條邊,要么是兩條相鄰的邊,問方案數。

\(O(n^2)\)的暴力呼之欲出,我們記\(f[i][0/1]\)表示處理完\(i\)的子樹,\(i\)向父親的這條邊是否與子樹內的邊組合了。

轉移的時候,我們只需要知道所有兒子中有幾個0,也就是有幾條邊需要我們來分配。

不妨再DP預處理出一個數組\(g[i][0/1]\),表示一個點下面掛著i條邊,要分配集合,i的父親邊是否參與的方案數。

我們考慮每次新加一條邊,要么自成集合,要么與之前的某一個組合,有
\(g[i][0]=g[i-1]+g[i-2][0]*(i-1),g[i][1]=g[i-1][0]*i\)

由于只要知道有幾個0,這顯然可以分治NTT優化,這樣就做完了。
時間復雜度\(O(n\log^2 n)\)

Code

以下代碼未經測試,完全不能保證正確性。
(慘遭證偽,請勿參考)

#include <bits/stdc++.h>
#define fo(i,a,b) for(int i=a;i<=b;++i)
#define fod(i,a,b) for(int i=a;i>=b;--i)
#define N 200005
#define M 524288
using namespace std;
const int mo=998244353;
typedef long long LL;
int n,m1,fs[N],nt[2*N],dt[2*N];
LL f[N][2],g[N];
LL ksm(LL k,LL n)
{LL s=1;for(;n;n>>=1,k=k*k%mo) if(n&1) s=s*k%mo;return s;
}
void link(int x,int y)
{nt[++m1]=fs[x];dt[fs[x]=m1]=y;
}
namespace poly
{int len,st[N],le[N],a[M+1];int u1[M+1],u2[M+1],l2[M+1],cf[20],wg[M+1],wi[M+1],ny[M+1],bit[M+1];void init(){fo(i,0,18) l2[cf[i]=(1<<i)]=i;fod(i,M-1,2) if(!l2[i]) l2[i]=l2[i+1];wg[0]=1,wg[1]=ksm(3,(mo-1)/M);ny[1]=1;fo(i,2,M) wg[i]=(LL)wg[i-1]*wg[1]%mo,ny[i]=(-(LL)ny[mo%i]*(mo/i)%mo+mo)%mo;}void prp(int num){int p=M/num,w=cf[l2[num]-1];fo(i,0,num-1) bit[i]=(bit[i>>1]>>1)|((i&1)<<w),wi[i]=wg[i*p];}int inc(int x,int y) {x+=y;return(x>=mo)?x-mo:x;}int dec(int x,int y) {x-=y;return(x<0)?x+mo:x;}void DFT(int *a,int num){fo(i,0,num-1) if(i<bit[i]) swap(a[i],a[bit[i]]);for(int h=1,l=num>>1;h<num;h<<=1,l>>=1){for(int j=0;j<num;j+=(h<<1)){int *x=a+j,*y=x+h,*w=wi,v;for(int i=0;i<h;i++,x++,y++,w+=l){v=(LL)(*x)*(*y)%mo;*y=dec(*x,v),*x=inc(*x,v);}}}}void IDFT(int *a,int num){DFT(a,num);fo(i,0,num-1) a[i]=(LL)a[i]*ny[num]%mo;reverse(a+1,a+num);}void doit(int l,int r){if(l==r) return; int mid=(l+r)>>1;doit(l,mid),doit(mid+1,r);int num=cf[l2[le[l]+le[mid+1]-1]];prp(num);memset(u1,0,4*num),memset(u2,0,4*num);fo(i,0,le[l]-1) u1[i]=a[st[l]+i];fo(i,0,le[mid+1]-1) u2[i]=a[st[mid]+i];DFT(u1,num),DFT(u2,num);fo(i,0,num-1) u1[i]=(LL)u1[i]*u2[i]%mo;IDFT(u1,num);le[l]+=le[mid+1]-1;fo(i,0,le[l]-1) a[st[l]+i]=u1[i];}
}
using namespace poly;void dfs(int k,int fa)
{for(int i=fs[k];i;i=nt[i]) {int p=dt[i];if(p!=fa) dfs(p,k);}len=0;int cnt=0;for(int i=fs[k];i;i=nt[i]){int p=dt[i];if(p!=fa){cnt++;a[st[cnt]=len++]=f[p][1];a[len++]=f[p][0];le[cnt]=2;}}if(!cnt) f[k][0]=1;else{doit(1,cnt);f[k][0]=f[k][1]=0;fo(i,0,le[1]-1){f[k][0]=(f[k][0]+(LL)a[i]*g[i])%mo;if(i) f[k][1]=(f[k][1]+(LL)a[i]*g[i-1]%mo*(LL)i)%mo;}}
}
int main()
{cin>>n;fo(i,1,n-1){int x,y;scanf("%d%d",&x,&y);link(x,y),link(y,x);}g[0]=1,g[1]=1;fo(i,2,n) g[i]=(g[i-1]+g[i-2]*(i-1))%mo;init();dfs(1,0);printf("%lld\n",f[1][0]);
}

轉載于:https://www.cnblogs.com/BAJimH/p/10945891.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/448842.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/448842.shtml
英文地址,請注明出處:http://en.pswp.cn/news/448842.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

注解 @PostConstruct 與 @PreDestroy 詳解及實例

簡介 前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 Java EE5 引入了PostConstruct和PreDestroy這兩個作用于Servlet生命周期的注解&#xff0c;實現Bean初始化之前和銷毀之前的自定義操…

別讓6種不良心理偷走你的好人緣

眾所周知&#xff0c;擁有正常、健康的交際圈對于人的身心健康都是很有幫助的。但是若想維系好自己的交際圈&#xff0c;也是很不容易的&#xff0c;甚至在不經意間產生的某些心理&#xff0c;就會直接給大家的人際交往帶來影響。那么接下來&#xff0c;小編就先為大家歸納一下…

PHP 安裝xdebug

xdebug官網: https://xdebug.org 安裝步驟如下: 使用 phpinfo() 打印出PHP相關信息, 全選, 復制 打開 xdebug 網站: https://xdebug.org/wizard.php 在圖中輸入框中粘貼你復制的信息, 點擊 Analyse my phpinfo() output 在結果中點擊下載, 然后按照它提示的步驟進行操作即可…

apt-clone:備份已安裝的軟件包并在新的 Ubuntu 系統上恢復它們

當我們在基于 Ubuntu/Debian 的系統上使用 apt-clone&#xff0c;包安裝會變得更加容易。如果你需要在少量系統上安裝相同的軟件包時&#xff0c;apt-clone 會適合你。 如果你想在每個系統上手動構建和安裝必要的軟件包&#xff0c;這是一個耗時的過程。它可以通過多種方式實現…

分布式消息中間件 : Rocketmq

簡述 前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 分布式消息中間件&#xff0c;主要是實現分布式系統中解耦、異步消息、流量銷鋒、日志處理等場景。生產中用的最多的消息隊…

PV、UV、UIP、VV、CPC、CPM、RPM、CTR指的是什么?

PV(PageView)&#xff1a;網站瀏覽量&#xff0c;指頁面的瀏覽次數&#xff0c;用以衡量網站用戶訪問的網頁數量。用戶沒打開一個頁面便記錄1次PV&#xff0c;多次打開同一頁面則瀏覽量累計&#xff1b;UV(UniqueVistor)&#xff1a;獨立訪客數&#xff0c;指1天內訪問某站點的…

linux opencl(AMD) Example

最近對并行計算很感興趣。不過搞MPI對我來說暫時沒什么用&#xff0c;基于GPU的并行計算倒是挺實用。網上的資料都是CUDA的。實質上我對CUDA一點興趣都沒有。無論別人的架構多么先進&#xff0c;我這個只有AMD顯卡的小孩都是旁觀者而已。在這里記錄一下一個opencl程序的編譯過程…

php使用supervisor管理進程腳本

supervisor是用python開發的一個在linux系統下的進程管理工具&#xff0c;可以方便的監聽&#xff0c;啟動&#xff0c;停止一個或多個進程。當一個進程被意外殺死后&#xff0c;supervisor監聽到后&#xff0c;會自動重新拉起進程。 一、supervisor的安裝 1、通過easy_install…

重寫規則和重載規則

重寫規則&#xff1a; 發生在有繼承關系的類之間&#xff08;同一類就是重載了&#xff09;相同的方法名&#xff0c;參數列表&#xff0c;返回類型可見性&#xff08;public,protected,private&#xff09;不能被縮小異常不能被放大規則與c中不一樣靜態類型不能被重寫方法重載…

消息中間件:RocketMQ 介紹(特性、術語、原理、優缺點、消息順序、消息重復)

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 消息中間件的作用 1. 應用解耦 2. 異步處理 比如用戶注冊場景&#xff0c;注冊主流程完成以后&#xff0c;需要調用郵件系統發送郵件…

C# JsonHelper類

記錄一下&#xff0c;方便下次用。 public class JsonHelper{#region Json/// <summary>/// JavaScriptSerializer/// </summary>/// <typeparam name"T"></typeparam>/// <param name"obj"></param>/// <returns&…

[譯】Redux入門教程(一)

前言 老外寫技術文章真是叼&#xff0c;這是國外的一個程序員寫的一個簡單易懂,循序漸進的Redux教程&#xff0c;本著共享的精神&#xff0c;就翻譯出來給大家一起看&#xff0c;文章最后有鏈接&#xff0c;不想看我翻譯的直接去看原文吧。 下面是原教程的英文目錄 這篇先更三分…

使用 Intellij Idea 打包 java 工程為可執行 jar 包

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 其實還有個簡單多了方法&#xff0c;見&#xff1a; 超簡單方法&#xff1a; Intellij Idea 把 java 工程打成可運行的 jar 步驟&#x…

QuickStart系列:docker部署之Gitlab本地代碼倉庫

gitlab是可以在本地搭建的使用git作為源代碼管理的倉庫。 運行環境&#xff1a; win10vmware14docker7docker 1. 使用命令拉取鏡像&#xff08;非必須&#xff0c;耗時比較久&#xff0c;這里以ce為準&#xff0c;ce是社區版&#xff0c;ee是企業版&#xff09;&#xff1a; do…

超簡單方法: Intellij Idea 把 java 工程打成可運行的 jar

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. 找到 Intellij Idea 最下面的 Terminal 選項&#xff0c;并點擊進入該界面。 2. 在光標位置輸入命令&#xff1a;mvn clean 。清理…

LDAP-輕量級目錄訪問協議(統一認證)

概念 LDAP是輕量目錄訪問協議&#xff0c;英文全稱是Lightweight Directory Access Protocol&#xff0c;一般都簡稱為LDAP。 參考資料 LDAP概念和原理介紹 我花了一個五一終于搞懂了OpenLDAP LDAP-Apache Directory Studio使用&#xff08;創建DC.OU及用戶&#xff09; 轉載于…

kafka集群搭建(消息)

1、Kafka使用背景在我們大量使用分布式數據庫、分布式計算集群的時候&#xff0c;是否會遇到這樣的一些問題&#xff1a;我們想分析下用戶行為&#xff08;pageviews&#xff09;&#xff0c;以便我們設計出更好的廣告位我想對用戶的搜索關鍵詞進行統計&#xff0c;分析出當前的…

[轉]在Windows 下使用OpenCL

目前&#xff0c;NVIDIA和AMD的Windows driver均有支援OpenCL&#xff08;NVIDIA的正式版driver是從195.62版開始&#xff0c;而AMD則是從9.11版開始&#xff09;。NVIDIA的正式版driver中包含OpenCL.dll&#xff0c;因此可以直接使用。AMD到目前為止&#xff0c;則仍需要安裝其…

docker 之 Dockerfile 實踐

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 上一篇介紹了Dockerfile中使用的指令&#xff0c;現在開始進行指令實踐 先查看下本地的鏡像&#xff0c;選一個作為base image&#xf…

tomcat啟動后命令行日志中文亂碼

這是日志的編碼設置和窗體的編碼格式不一致。 將 conf\logging.properties 文件中的 UTF-8 改成 GBK 重啟tomcat &#xff08;右鍵cmd標題欄部分&#xff0c;可以查看cmd屬性&#xff09; 轉載于:https://www.cnblogs.com/Echiops/p/10974587.html