ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

20220722

2022-07-31 10:02:27  阅读:138  来源: 互联网

标签:int mid void 20220722 t0 t1 siz2


染色

要求环上没有重复点,可以先求个点双。对每个点双分类讨论:

  • 边数 \(<\) 点数:该点双中只有两个点一条边,该边不在任何环中,可以随意染色
  • 边数 \(=\) 点数:该点双是一个环。根据 Burnside 引理,方案数为 \(\frac{1}{n}\sum_{i=0}^{n-1}k^{\gcd(i,n)}\)
  • 边数 \(>\) 点数:该点双由若干环套起来,只要每种颜色的个数相同就本质相同,直接插板法算方案数
    证明:肯定存在一个三度点(一定有两个环在该点相交),手玩一下可以发现可以在不影响其他边的情况下交换该点的两邻边,进而可以任意交换两边(先把这两边移到三度点旁边,交换后再移回去)

实现上注意有重边,应该令割点属于 dfs 树上最浅的点双,边属于 dfs 树上较深的点双

code
const int N = 5e5+5;
int n,m,mm=1,ind,dcc,head[N],nxt[N*4],to[N*4],dfn[N],low[N],in[N],siz1[N],siz2[N];
mint k,ans(1);

auto C=[](mint n,int m) {
	mint res(1);
	For(i,1,m) res *= (n-i+1) / i;
	return res;
};

void tj(int u) {
	static int stk[N],tp;
	dfn[u] = low[u] = ++ind, stk[++tp] = u;
	for(int i = head[u], v; v = to[i], i; i = nxt[i])
		if( dfn[v] ) ckmin(low[u],dfn[v]);
		else {
			tj(v), ckmin(low[u],low[v]);
			if( dfn[u] <= low[v] ) {
				++dcc, ++siz1[dcc];
				do in[stk[tp--]] = dcc, ++siz1[dcc]; while( stk[tp+1] != v );
			}
		}
}

signed main() { freopen("painting.in","r",stdin); freopen("painting.out","w",stdout);
	io>>n>>m>>k.x;
	For(i,1,m, x,y)
		io>>x>>y,
		nxt[++mm] = head[x], to[mm] = y, head[x] = mm,
		nxt[++mm] = head[y], to[mm] = x, head[y] = mm;
	For(i,1,n) if( !dfn[i] ) tj(i), in[i] = inf;
	for(int i = 2; i < mm; i += 2) ++siz2[min(in[to[i]],in[to[i^1]])];
	For(i,1,dcc)
		if( siz2[i] == 1 ) ans *= k;
		else if( siz1[i] == siz2[i] ) {
			mint res;
			Rep(j,0,siz2[i]) res += Pow(k,__gcd(j,siz2[i]));
			ans *= res / siz2[i];
		} else ans *= C(k+siz2[i]-1,siz2[i]);
	io<<ans.x;
	return 0;
}

序列计数问题

经典题,以前见过但没做。。。

先把 \(n,c\) 都 \(-1\)

考虑容斥,枚举超过限制的 \(x\),答案即为

\[\sum_{s\subseteq U}(-1)^{|s|}{n+m-c|s|-\sum_{i\in s}b^{i}\choose m} \]

枚举 \(|s|\),那么 \(a=n+m-c|s|\) 是定值。在 \(x=\sum_{i\in s}b^{i}\le a\) 的情况下 \({a-x\choose m}\) 是关于 \(x\) 的 \(m\) 次多项式,\(O(m^{2})\) 暴力计算出系数后代入 \(\sum x\) 即可求出 \(\sum{a-x\choose m}\)

剩下的问题是计算 \(x\) 的次幂。可以枚举 \(x\) 与 \(a\) 在 \(b\) 进制下 LCP 的下一位(注意到 \(x\) 在 \(b\) 进制下每位为 \(0/1\)),当前位 \(x<a\),那么低位可以随便填。预处理 \(g[i,j,k]\) 表示后 \(i\) 位,有 \(j\) 位为 \(1\),和的 \(k\) 次幂。使用二项式定理转移和合并高低位即可

实现上可以记录 \(c\) 的正负,并在高精减前判断大小,这样就不用写高精负数了。细节比较多

时间复杂度 \(O(m^{3}\log n)\)

code

计算机

sub 1

读题分,手玩即可

out
NOT 2 2
RSH 2 61
LSH 2 3
NOT 3 3
RSH 3 62
LSH 3 9
NOT 4 4
RSH 4 63
LSH 4 1
SET 1 2
OR 3 3 4
OR 1 1 3

sub 2

用 \(a_{i},b_{i}\) 表示两个数二进制第 \(i\) 位的值,\(c_i\) 表示第 \(i\) 位是否进位,那么 \(a+b=a\oplus b\oplus2c\)

注意到并行对分治结构是利好的,比如线段树建树复杂度变为 \(\log 64\)。如果能把 \(c\) 表示成具有结合律的信息,就可以类似 DDP 一样挂到线段树上。

考虑 \(c\) 的递推过程:

  • \(a_{i}=b_{i}=1\):\(c_{i}=1\)
  • \(a_{i}=b_{i}=0\):\(c_{i}=0\)
  • \(a_{i}=1\vee b_{i}=1\):\(c_{i}=c_{i-1}\)

考虑对每个区间维护 \(t0[i],t1[i]\) 表示 \(c_{l-1}=0/1\) 时 \(c_{i}\) 的值,合并时使用 \(t0[mid],t1[mid]\) 更新 \([mid+1,r]\) 的值即可

code
int n=4,a[64],b[64],t0[64],t1[64];
uLL ans,x[401];

void SET(int i,int j) { x[i] = x[j]; printf("SET %d %d\n",i,j); }
void XOR(int i,int j,int k) { x[i] = x[j]^x[k]; printf("XOR %d %d %d\n",i,j,k); }
void AND(int i,int j,int k) { x[i] = x[j]&x[k]; printf("AND %d %d %d\n",i,j,k); }
void OR(int i,int j,int k) { x[i] = x[j]|x[k]; printf("OR %d %d %d\n",i,j,k); }
void LSH(int i,int j) { x[i] <<= j; printf("LSH %d %d\n",i,j); }
void RSH(int i,int j) { x[i] >>= j; printf("RSH %d %d\n",i,j); }
void NOT(int i,int j) { x[i] = ~x[j]; printf("NOT %d %d\n",i,j); }

#define mid (l+r>>1)
void bld(int l,int r) {
	if( l == r ) return;
	bld(l,mid), bld(mid+1,r);
	For(i,mid+1,r)
		AND(3,t1[mid],t1[i]), AND(4,t0[mid],t1[i]),
		OR(t1[i],t0[i],3), OR(t0[i],t0[i],4);
}
void qry(int l,int r) {
	if( l == r ) {
		if( l ) SET(b[l],t0[l-1]), LSH(b[l],l);
		else SET(b[l],2);
		return;
	}
	qry(l,mid), qry(mid+1,r), XOR(b[l],b[l],b[mid+1]);
}

signed main() { freopen("cal2.out","w",stdout);
	scanf("%llu %llu",&x[1],&x[2]), ans = x[1]+x[2];
	NOT(400,400), RSH(400,63);
	Rep(i,0,64)
		a[i] = ++n, SET(n,1), RSH(n,i), AND(n,n,400),
		b[i] = ++n, SET(n,2), RSH(n,i), AND(n,n,400);
	Rep(i,0,64) t0[i] = ++n, AND(t0[i],a[i],b[i]), t1[i] = a[i], OR(t1[i],a[i],b[i]);
	bld(0,63), qry(0,63);
	XOR(1,1,b[0]);
	assert(n<=400), assert(ans==x[1]);
	return 0;
}

sub 3

标签:int,mid,void,20220722,t0,t1,siz2
来源: https://www.cnblogs.com/401rk8/p/16536493.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有