AtCoder AGC043C Giant Graph (teoría de grafos, la función SG, FWT)

tema Enlace

https://atcoder.jp/contests/agc043/tasks/agc043_c

solución del problema

La sensación corte nada que renunciar a la idea, como un campo de diez minutos bajo problema del agua se encuentra, la pérdida de sangre. . . (Los únicos culpables demasiado migajas no pueden hacer que el nivel de recuento D)
En primer lugar, al parecer por \ ((i + j + k ) \) descendiendo codiciosos, teniendo en cuenta el punto de vista tiene solamente una dimensión, nos dará ninguna orientación lado a, desde el punto más bajo de referencia fijado sobre la etiqueta un gran conjunto de puntos \ (U \) señala el punto de ajuste a \ (ADJ [U] \) , \ (F [U] \) representa \ (U \) punto si elección, a continuación, \ (f [U] = \ neg \ or_ {v \ en ADJ [T]} f [v] \) .
observe cuidadosamente esta fórmula, lo que puede pensar? SG función! Este \ (f [u] \) hay otro sentido: en el gráfico de \ (U \) punto tiene una pieza, tiene operación a su vez parte, cada vez que una pieza a lo largo de un borde mueve fuera, la salida no puede mover , la \ (f [u] \) de \ (1 \) representa el punto de perder la ventaja, como \ (0 \) que representa los puntos de ganar mano superiores.
Así, en el caso de tres dimensiones (o incluso más dimensiones) enfoque también es clara: el equivalente a una superposición multidimensional de múltiples juegos, a continuación, utilizar la función SG resuelto, la respuesta igual a \ (\ sum_ {sg [U_1 ] \ oplus sg [u_2] \ SG Oplus = 0} (10 ^ 18 es {}) ^ {} U_3 U_1 + + U_2 \) [U_3] , es decir, una secuencia de secuencia de tres convolución XOR, se obtiene la respuesta final\ (0 \) valor a.
complejidad de tiempo \ (O (n \ n log) \) .

código

#include<bits/stdc++.h>
#define llong long long
#define mkpr make_pair
#define riterator reverse_iterator
#define y1 Lorem_ipsum_dolor
using namespace std;

inline int read()
{
	int x = 0,f = 1; char ch = getchar();
	for(;!isdigit(ch);ch=getchar()) {if(ch=='-') f = -1;}
	for(; isdigit(ch);ch=getchar()) {x = x*10+ch-48;}
	return x*f;
}

const int mxN = 1<<17;
const int P = 998244353;
const llong Inv2 = 499122177ll;
const llong W = 716070898ll;
int sg[mxN+3];
llong pwW[mxN+3];
llong f[3][mxN+3],g[mxN+3];
vector<int> adj[mxN+3]; vector<int> vec;
int n,m,dgr;

int get_mex()
{
	int ret = 0; sort(vec.begin(),vec.end());
	for(int i=0; i<vec.size(); i++)
	{
		if(vec[i]==ret) {ret++;}
		else if(vec[i]>ret) {break;}
	}
	vec.clear(); return ret;
}

void fwt(int dgr,int coe,llong poly[],llong ret[])
{
	for(int i=0; i<(1<<dgr); i++) ret[i] = poly[i];
	for(int i=1; i<(1<<dgr); i<<=1)
	{
		for(int j=0; j<(1<<dgr); j+=(i<<1))
		{
			for(int k=0; k<i; k++)
			{
				llong x = ret[j+k],y = ret[j+i+k];
				ret[j+k] = (x+y)%P,ret[j+i+k] = (x-y+P)%P;
				if(coe==-1) {ret[j+k] = ret[j+k]*Inv2%P,ret[j+i+k] = ret[j+i+k]*Inv2%P;}
			}
		}
	}
}

int main()
{
	scanf("%d",&n); while((1<<dgr)<=n) dgr++;
	pwW[0] = 1ll; for(int i=1; i<=n; i++) pwW[i] = pwW[i-1]*W%P;
	for(int T=0; T<3; T++)
	{
		scanf("%d",&m);
		for(int i=1; i<=m; i++)
		{
			int u,v; scanf("%d%d",&u,&v);
			if(u>v) {swap(u,v);} adj[u].push_back(v);
		}
		for(int i=n; i>=1; i--)
		{
			for(int o=0; o<adj[i].size(); o++)
			{
				vec.push_back(sg[adj[i][o]]);
			}
			sg[i] = get_mex();
//			printf("sg[%d]=%d\n",i,sg[i]);
			f[T][sg[i]] = (f[T][sg[i]]+pwW[i])%P;
		}
		for(int i=1; i<=n; i++) adj[i].clear(),sg[i] = 0;
		fwt(dgr,1,f[T],f[T]);
	}
	for(int i=0; i<(1<<dgr); i++) {g[i] = f[0][i]*f[1][i]%P*f[2][i]%P;}
	fwt(dgr,-1,g,g);
	printf("%lld\n",g[0]);
	return 0;
}

Supongo que te gusta

Origin www.cnblogs.com/suncongbo/p/12556364.html
Recomendado
Clasificación