2019牛客暑期多校训练营(第九场)——All men are brothers(逻辑推理)

original link - https://ac.nowcoder.com/acm/contest/889/E

题意:

给出n个人,开始每个人独立。然后每次操作选择两个人,连接两个人所在的集合。问每次操作后,我选择4个人不在一个集合的方案数。

解析:

最开始的时候,A4A4A4表示选择4个人的方案数,为:Cn4C_n^4Cn4​,A3,A2,A1A3,A2,A1A3,A2,A1同理。

然后维护连接两个集合的影响,设两个集合的大小为:x,yx,yx,y。


定义F(n,x)F(n,x)F(n,x)为选择nnn个人且包括了xxx的方案数,F(n,y)F(n,y)F(n,y)同。

那么新的A4A4A4应该为:A4F(4,xy)+(x+y)F(3,¬x¬y)A4-F(4,x\vee y)+(x+y)F(3,\neg x\wedge\neg y)A4−F(4,x∨y)+(x+y)F(3,¬x∧¬y)

我会减去选择其中任意一个的方案,加上选择合并后的那堆再另外选择3堆的方案

F(4,xy)=xF(3,¬x)+yF(3,¬y)xyF(2,¬x¬y)F(3,¬x)=A3F(3,x)F(3,x)=xF(2,¬x)F(2,¬x)=A2F(2,x)F(2,x)=xF(1,¬x)F(1,¬x)=A1x...F(2,¬x¬y)=A2F(2,xy)...F(4,x\vee y)=xF(3,\neg x)+yF(3,\neg y)-xyF(2,\neg x\wedge\neg y)\\F(3,\neg x)=A3-F(3,x)\\F(3,x)=xF(2,\neg x)\\F(2,\neg x)=A2-F(2,x)\\F(2,x)=xF(1,\neg x)\\F(1,\neg x)=A1-x\\...\\F(2,\neg x\wedge\neg y)=A2-F(2,x\vee y)\\...F(4,x∨y)=xF(3,¬x)+yF(3,¬y)−xyF(2,¬x∧¬y)F(3,¬x)=A3−F(3,x)F(3,x)=xF(2,¬x)F(2,¬x)=A2−F(2,x)F(2,x)=xF(1,¬x)F(1,¬x)=A1−x...F(2,¬x∧¬y)=A2−F(2,x∨y)...
然后维护一下A3,A2:A3,A2:A3,A2:
A3F(3,xy)+(x+y)F(2,,¬x¬y)...A3-F(3,x\vee y)+(x+y)F(2,,\neg x\wedge\neg y)\\...A3−F(3,x∨y)+(x+y)F(2,,¬x∧¬y)...
反正到最后每个东西都是可以推出来的,每次输出一下A4A4A4就行了。

代码:

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define LLL __int128
LLL A4,A3,A2,A1;
 
const int maxn=1e5+9;
int fa[maxn];
int siz[maxn];
int fin(int a){
    return fa[a]==a?a:fa[a]=fin(fa[a]);
}
 
int main(){
    LL n,m;
    scanf("%lld%lld",&n,&m);
    int sum=n;
    LLL One=1;
    A1=n,A2=n*(n-1)/2,A3=One*A2*(n-2)/3,A4=One*A3*(n-3)/4;
    rep(i,1,n)fa[i]=i,siz[i]=1;
    printf("%lld\n",(LL)A4);
    while(m--){
        int a,b;scanf("%d%d",&a,&b);
        int f1=fin(a),f2=fin(b);
        if(f1==f2){
            printf("%lld\n",(LL)A4);
            continue;
        }
        LLL x=siz[f1],y=siz[f2];
        fa[f1]=f2;
        siz[f2]+=siz[f1];
        sum--;
        if(sum<4){
            printf("0\n");
            A4=0;
            continue;
        }
        LLL  _1notx=A1-x,
            _1noty=A1-y,
            _1notxnoty=A1-x-y,
            _2xory=x*_1notx-x*y+y*_1noty,
            _2notxnoty=A2-_2xory,
            _2x=x*_1notx,
            _2y=y*_1noty,
            _2notx=A2-_2x,
            _2noty=A2-_2y,
            _3x=x*_2notx,
            _3y=y*_2noty,
            _3notx=A3-_3x,
            _3noty=A3-_3y,
            _3xory=x*_2notx-x*y*_1notxnoty+y*_2noty,
            _3notxnoty=A3-_3xory,
            _4xory=x*_3notx-x*y*_2notxnoty+y*_3noty;
 
        A4-=_4xory;
        A4+=(x+y)*_3notxnoty;
        A3-=_3xory;
        A3+=(x+y)*_2notxnoty;
        A2-=_2xory;
        A2+=(x+y)*_1notxnoty;
        printf("%lld\n",(LL)A4);
    }
}
上一篇:笔记 - 最短路


下一篇:[省选前集训2022] 模拟赛5