• AT5800 [AGC043C] Giant Graph 题解


    Codeforces
    Luogu

    Description.

    有三个无向图 \(G_1,G_2,G_3\),均有 \(n\) 个点。
    以这三个图构造一个有 \(n^3\) 个点的无向图 \(G\),构造方式如下:

    1. \(\forall (u,v)\in G_1,\forall x,y\in[1,n],((u,x,y),(v,x,y))\in G\)
    2. \(\forall (u,v)\in G_2,\forall x,y\in[1,n],((x,u,y),(x,v,y))\in G\)
    3. \(\forall (u,v)\in G_3,\forall x,y\in[1,n],((x,y,u),(x,y,v))\in G\)

    新图 \((a,b,c)\) 点权是 \(10^{18(a+b+c)}\)
    问最大独立集。

    Solution.

    考虑 \(10^{18}\) 是一个很大的数,可以把它当作 \(+\infty\)
    这样我们的贪心选择 \(a+b+c\) 最大的点贪心选上,这样肯定是正确的。
    我们对于三张图,可以给边定向,指定大的指向小的。
    对于一张图,最优决策可以看成是 \(SG\) 函数。
    三张图互不干扰 \(SG\) 函数就是 \(\oplus\),可以直接 FWT

    Coding.

    点击查看代码
    //是啊,你就是那只鬼了,所以被你碰到以后,就轮到我变成鬼了{{{
    #include<bits/stdc++.h>
    using namespace std;typedef long long ll;
    template<typename T>inline void read(T &x)
    {
    	x=0;char c=getchar(),f=0;
    	for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
    	for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    	f?x=-x:x;
    }
    template<typename T,typename...L>inline void read(T &x,L&...l) {read(x),read(l...);}//}}}
    const int P=998244353,N=100005;
    inline int ksm(int x,int q=P-2) {int r=1;for(;q;q>>=1,x=1ll*x*x%P) if(q&1) r=1ll*r*x%P;return r;}
    int n,m,sg[3][N],tn[1025],sz[3][1025];vector<int>ef[N];
    inline void solve(int *a)
    {
    	read(m);for(int i=1;i<=n;i++) ef[i].clear();
    	for(int i=1,x,y;i<=m;i++) read(x,y),ef[min(x,y)].push_back(max(x,y));
    	for(int i=n;i>=1;i--)
    	{
    		for(int x:ef[i]) tn[a[x]]=1;
    		for(int w=0;;w++) if(!tn[w]) {a[i]=w;break;}
    		for(int x:ef[i]) tn[a[x]]=0;
    	}
    }
    inline void FWT(int n,int *a,char fg)
    {
    	for(int d=1;d<n;d<<=1) for(int i=0;i<n;i+=d+d) for(int j=i;j<i+d;j++)
    		{int x=a[j],y=a[j|d],w=fg?(P+1)>>1:1;a[j]=1ll*(x+y)*w%P,a[j|d]=1ll*(x-y+P)*w%P;}
    }
    int main()
    {
    	read(n);for(int i=0;i<3;i++) solve(sg[i]);
    	int mx=0;for(int i=0;i<3;i++) for(int j=1;j<=n;j++) mx=max(mx,sg[i][j]);
    	int T=1,pw=1000000000000000000%P;while(T<=mx) T<<=1;
    	for(int i=0;i<3;i++) for(int j=1;j<=n;j++) sz[i][sg[i][j]]=(sz[i][sg[i][j]]+ksm(pw,j))%P;
    	FWT(T,sz[0],0),FWT(T,sz[1],0),FWT(T,sz[2],0);
    	for(int i=0;i<T;i++) sz[0][i]=1ll*sz[0][i]*sz[1][i]%P*sz[2][i]%P;
    	return FWT(T,sz[0],1),printf("%d\n",sz[0][0]),0;
    }
    
  • 相关阅读:
    对象
    函数3
    函数2-作用域
    事件的分类
    函数1
    简单了解JSON Web令牌(JWT)
    Pycharm激活码,2020年9月29日最新激活码
    Python基础学习之常用模块
    python详细图像仿射变换讲解
    Python如何快速复制序列?
  • 原文地址:https://www.cnblogs.com/pealfrog/p/15476123.html
Copyright © 2020-2023  润新知