jzoj4424
20%:暴力枚舉每一條邊有沒有被選到,然後使用并查集判斷聯通性
這樣子有20分,但是我考試寫掛了所以1分也沒有
100%:這道題2000的數據範圍,使用指數級搜索會tle,需要更加好的方法
這道題中,可以設f[n]表示節點數為n,且整個圖必須得聯通的方案數
g[n]為節點數為n,但是整個圖不必聯通的方案數
則g[n]=2^(n-1)(n)/2,因為我們可以選和不選每一條邊,都可以對方案產生貢獻
而f[n]屬於g[n],因為當一個方案聯通時,它一定不必聯通,但是一個方案不必聯通,則這個方案不一定是聯通的,所以我們可以將g數組減去幾個數得到f數組就可以正確的計算出有多少種方案合法
我們可以知道一個方程,f[n]=g[n]-sigma(i=1~n-1)c(n-1,i-1)*f[i]*g[n-i]
為什麼?我們可以將整個圖分成2個部分,大小分別為i和n-i
我們可以強制性的將聯通塊分到第n節點,然後去掉n節點考慮影響
現在,設包含n的聯通塊的大小為i,則其他部分的大小為n-i。
我們可以不在這些聯通塊中連邊,這樣子圖一定不連通
所以,方案數=強制選擇n,聯通塊大小為i的方案數*選擇i個節點,必須使這i個節點聯通的方案數乘上選擇n-i個節點,不必使這些節點聯通的方案數
也就是c(n-1,i-1)*f[i]*g[n-i]
但是這種方案有一個疑點:萬一我們兩邊圖都可以不連通呢?會不會算漏呢?
不存在的。因為我們選出來這i個節點不連通,但是在由這i個節點組成的點集中,一定有包含節點n的聯通塊,而這種方案已經算過了,所以不會算漏
這樣,我們就求出了由n個節點構成的圖,有多少種方案使整個圖必須聯通
但是,這道題要求的是平方和。所以還要知道怎麼計算這個平方和
f,g數組要設多1維0/1/2,表示統計的是0次方/1次方/2次方和
我們考慮g數組怎麼計算,設d=n*(n-1)/2
則g[n][0]=2^d
g[n][1],設現在連了x條邊,則對答案的貢獻為x*c[d][x],可以加起來算
但是這個方法不夠優,我們可以考慮一下每條邊選了以後,會對答案造成多少的貢獻
所以ans=d*每條邊可以選的次數
其他邊可以隨便亂選,有2^(d-1)種方案
所以ans=d*2^(d-1)
同理,考慮向方案中添加一條邊會變成怎麼樣
我們要計算恰好包含這條邊的方案,就知道多了多少種方案
原來,每一種方案是sigma(i)num[i]^2,設其等於v
現在變成了sigma(i)(num[i]+1)^2
轉化為v+sigma(i)2k+1
sigma(i)1很顯然等於g[n][1]
但是sigma(i)2k所產生的所有方案,當前邊必須固定選,剩下來d-1條邊,所以等於2(d−1)∗2^(d−2)
但是這個算法有點缺陷,因為如果那條邊選了,這條邊也選,再接一些奇怪的方案,與這條邊選了,那條邊也選,再接同一種方案,是一樣的
所以實際上答案只有(d−1)∗2^(d−2)
總共為d∗2^(d−1)+d(d−1)∗2^(d−2)
計算出d=n*(n-1)/2的時候的方案數就是答案g[n][2]
這樣子計算出了g數組
關於f數組怎麼求
設一個輔助數組h,存的是一定使圖不連通的方案數
f[n][0]已經求出來了,所以h[n][0]也求出來了
再設a,b,分別為f[i],g[n-i]數組中方案的集合
則h[n][1]=sigma(i)sigma(j)(a[i]+b[j])
因為當我們將2個方案組合在一起時,新的方案會有a[i]+b[j]條邊,會產生a[i]+b[j]的答案
這樣還是很慢
但是,我們可以發現一個這樣子的東西,每一個a[i],b[i]都被加了g[n-i][0]次和f[n-i][0]次,所以這種方案對h的貢獻為sigma(a)*g[n-i][0]+sigma(b)*g[n-i][1]=f[i][0]*g[n-i][1]+f[n-i][1]*g[n-i][0]
再求出f[n][2]的值
h[n][2]=sigma(i)sigma(j)(a[i]+b[j])^2=sigma(i)sigma(j)(a[i]^2+b[j]^2+2*a[i]*b[j])
我們發現,所有的a[i]^2都被乘了g[n-i][0]次,所有的b[i]^2都被乘了f[n-i][0]次
還剩下一個sigma(i)sigma(j)2*a[i]*b[j]
這個的結果為(a[1]b[1]+a[1]b[2]+……+a[1]b[n]+a[2]b[1]+……+a[n]b[n])*2
提取公因式,變為(a[1]+a[2]+…+a[n])*(b[1]+b[2]+…+b[n])*2=f[i][1]*g[n-i][1]*2
所以h[n][2]=sigma(i)f[i][1]*g[n-i][1]*2+f[i][0]*g[n-i][1]+f[n-i][0]*g[n-i][0]
這樣子,我們就計算出了h[n][2]和h[n][1],與g相減就變為了f
這樣,我們就成功的解決了本題
代碼:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll c[2010][2010],f[2010][3],g[2010][3],n,m;
ll qp(ll x,ll y){
if(y<0)return 0;
if(!y)return 1;
if(y==1)return x%m;
ll r=qp(x,y/2)%m;
if(y&1)return r*r%m*x%m;
else return r*r%m;
}
int main(){
scanf("%lld%lld",&n,&m);
for(ll i=0;i<=n;i++){
c[i][0]=1;
for(ll j=1;j<=i;j++)
c[i][j]=(c[i-1][j-1]+c[i-1][j])%m;
}
f[1][0]=g[1][0]=1;
for(ll i=2;i<=n;i++){
ll d=i*(i-1)/2;
f[i][0]=g[i][0]=qp(2,d);
f[i][1]=g[i][1]=qp(2,d-1)*d%m;
f[i][2]=g[i][2]=(qp(2,d-1)*d+d*(d-1)%m*qp(2,d-2))%m;
}
for(ll i=2;i<=n;i++)
for(ll j=1;j<i;j++){
f[i][0]=(f[i][0]-c[i-1][j-1]*f[j][0]%m*g[i-j][0]%m+m)%m;
f[i][1]=(f[i][1]-c[i-1][j-1]*(f[j][0]*g[i-j][1]%m+f[j][1]*g[i-j][0]%m)%m+m)%m;
f[i][2]=(f[i][2]-c[i-1][j-1]*(f[j][0]*g[i-j][2]%m+f[j][1]*g[i-j][1]*2%m+f[j][2]*g[i-j][0]%m)+m)%m;
}
printf("%lld\n",(f[n][2]%m+m)%m);
return 0;
}
jzoj4424的更多相关文章
随机推荐
- 对于Android开发,啥是高级工程师?
最近一直在思考自己的技术方向.新的技术永远都是层出不穷,kotlin,flutter,小程序,轻应用等等,但是作为一个老鸟,新的东西,永远都是学不完的,想在新的技术上迭代学习出一个新高度,而增加自己的 ...
- windows常用运行命令总结
开始→运行→命令集锦 winver---------检查Windows版本 wmimgmt.msc----打开windows管理体系结构(WMI) wupdmgr--------windows更新程序 ...
- HTML5新协议介绍 WebSocket
WebSocket protocol 是HTML5一种新的协议(protocol).它是实现了浏览器与服务器全双工通信(full-duplex). 现在,很多网站为了实现即时通讯(real-time) ...
- 《计算机网络》谢希仁(第7版) 第四章 c语言http://c.biancheng.net/cpp/html/3137.html
第四章 网络层 电信网使用面向连接的通信方式,使电信网络能够向用户提供可靠传输的服务. 互联网设计思路:网络层向上只提供简单灵活的.无连接的.尽最大努力交付的数据报(分组)服务. 网络层不提供可靠传输 ...
- SQL思维导图
- 《JavaScript高级程序设计》笔记
1. 当在函数内部定义了其他函数时,就创建了闭包.闭包有权访问包含函数内部的所有变量. 2. 闭包可以分隔变量空间,不会占用全局空间而造成相互间的干拢.使用闭包可以在JavaScript中模仿块级作用 ...
- part1:4-linux快速体验
1.Linux部分目录结构介绍 /:根目录,一般根目录下只存放目录,尽量不要存放文件:/etc./bin./dev./lib./sbin应该和根目录放置在一个分区中. /bin:可执行二进制文件目录, ...
- 2018.07.25 bzoj3878: [Ahoi2014&Jsoi2014]奇怪的计算器(线段树)
传送门 线段树综合. 让我想起一道叫做siano" role="presentation" style="position: relative;"&g ...
- class和struct
相同点 实际上可以使用这两个关键字定义任何一个类. 区别 1.struct的默认成员访问说明符为public,class的默认成员访问说明符为private(什么叫默认?就是没有写明public.pr ...
- CentOS中的一些小技巧和特殊知识
一:软件: firefox 1.在tab栏右键可以打开上一次关闭的标签. 2.在上面的搜索栏可以添加搜索引擎,这样就不需要再打开标签页访问搜索引擎主页来搜索了. 3.获取firefox下载弹框的资源U ...