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的更多相关文章

随机推荐

  1. Template msg

    http://blog.csdn.net/xiejiawanwei2_bb/article/details/40680493 {{first.DATA}} 日期:{{Day.DATA}} 报警类型:{ ...

  2. JS 读取本地Excel文件

    首先我们先引用一个Excel的类库xlsx.full.min.js 中间处理: 'use strict'; var ExcelReader = { isFirstRead: true, fixdata ...

  3. xmlhttp

    File an issue about the selected textFile an issue about the selected text XMLHttpRequest Living Sta ...

  4. doctotext

    文档解析库 http://www.it610.com/article/1936051.htm

  5. 深入浅出 JMS(三) - ActiveMQ 安全机制

    深入浅出 JMS(三) - ActiveMQ 安全机制 一.认证 认证(Authentication):验证某个实体或者用户是否有权限访问受保护资源. MQ 提供两种插件用于权限认证: (一).Sim ...

  6. pyqt5和qtdesign的使用

    http://blog.csdn.net/Angelasan/article/details/44917283 发现我的使用时候有点跟他不同. 我是 g: utf- -*- # Form implem ...

  7. C和C++之间库的互相调用

    http://www.cppblog.com/wolf/articles/77828.html 昨晚有个朋友问我关于在C中调用C++库的问题,今天午饭后,由于脖子痛的厉害而没有加入到我们组的“每天一战 ...

  8. 大文件webuploader的基本使用

    webuploader的简单使用 需要的文件   自备  百度很多 webuploader.js  uploader.swf  jQuery <!DOCTYPE html> <htm ...

  9. org.apache.cxf 官方骨架

    mvn archetype:generate -DarchetypeCatalog=remote 用 cxf 筛选结果 官方三大项目骨架 org.apache.cxf:cxf-http-basic ( ...

  10. yum 常用命令

    yum是一个用于管理rpm包的后台程序,用python写成,可以非常方便的解决rpm的依赖关系.在建立好yum服务器后,yum客户端可以通过 http.ftp方式获得软件包,并使用方便的命令直接管理. ...