「Solution Set」7/3

P4433 [COCI2009-2010#1] ALADIN

我们发现就是区间加一个等差数列,但是要取模后的。

我们考虑加一个首项为 \(A\),公差为 \(B\),项数为 \(n\) 的等差数列,还要对 \(C\) 取模。

那么和就是这样的:\(\sum\limits_{i=0}^{n-1} Bi+A-\lfloor\frac {Bi+A}{C}\rfloor \times C\)

然后前面两项能用通项求,后面能用类欧求和。

然后就是线段树普通操作了!

就是因为空间 64MB 所以需要离散化,然后处理起来挺麻烦的吧((

P6139 【模板】广义后缀自动机(广义 SAM)

我仍然不理解 SAM.jpg

就是在每插入一个串的时候将 lst 置成 \(1\) 就行。

但是需要判一下此时 \(lst\) 有没有向 \(c\) 的出边。如果有的话,那就不应当新建节点,而是直接在原来的基础上做

void add(char c)
{
	int p=lst;
	if(st[lst].ch.count(c))
	{
		int q=st[p].ch[c];
		if(st[q].len==st[p].len+1) lst=q;
		else
		{
			int clone=++tot; st[clone].len=st[p].len+1; st[clone].fa=st[q].fa;
			st[clone].ch=st[q].ch;
			while(p!=-1&&st[p].ch[c]==q) st[p].ch[c]=clone,p=st[p].fa;
			st[q].fa=clone; lst=clone;
		}
		return;
	}
	int cur=++tot;  st[cur].len=st[lst].len+1;
	while(p!=-1&&!st[p].ch[c]) st[p].ch[c]=cur,p=st[p].fa;
	if(p==-1) st[cur].fa=1;
	else
	{
		int q=st[p].ch[c];
		if(st[q].len==st[p].len+1) st[cur].fa=q;
		else
		{
			int clone=++tot; st[clone].len=st[p].len+1; st[clone].fa=st[q].fa;
			st[clone].ch=st[q].ch;
			while(p!=-1&&st[p].ch[c]==q) st[p].ch[c]=clone,p=st[p].fa;
			st[cur].fa=st[q].fa=clone;
		}
	}   
	ans+=st[cur].len-st[st[cur].fa].len;
	lst=cur;
}

CF204E Little Elephant and Strings

考虑在 SAM 节点上线段树合并,然后求出来每个点是不是出现了 \(k\) 次以上。如果出现了 \(k\) 次以上,那么在这个节点上的答案就是 \(len[p]-len[fa]\),否则就是从parent tree 上最近的节点的串的数量。

我应该还是不理解 SAM 的说。

P4609 [FJOI2016] 建筑师

我们考虑最高的那个一定不会被挡住,所以可以以最高的那个为分界点,之后左右两边分别分成 \(A+B+2\) 组,每组都是最大的能露出来放在第一个,正好相当于圆排列。

所以答案就是

${n\brack {A+B-2}}\times {A+B-2\choose A-1} $

P2664 树上游戏

我们考虑对于每个颜色 \(j\) 求出 \(f_{i,j}\) 表示从 \(i\) 开始走,不经过 \(j\) 号颜色的方案数。答案就是 \(sum_i=\sum n-f_{i,j}\)

然后我们考虑只求 \(g_i=\sum f_{i,j}\)

我们遍历树的时候,\(p\) 节点的颜色是 \(i\),设从他到子树里别的节点不经过颜色 \(i\) 的节点数是 \(x\),那么这 \(x\) 个节点的 \(f_{v,i}=x\),所以求这个可以在记录每个点最近的子孙颜色相同的,然后树上差分。

[ABC284G] Only Once

你考虑从每个点开始是没有区别的,所以只需要算一个点的答案,然后乘 \(n\) 就行。

然后发现一定是先走一段直线,然后在一个环里循环。

那么可以先选出来会经过的点,然后枚举最先开始循环的位置,然后乱组合数一下

CF1342E Placing Rooks

首先可以知道如果所有都能被攻击到,那么肯定是每行都有或者每列都有。

那么算其中一种情况,乘 2 就行了。

发现 \(k>n\) 是一定无解。

然后发现一定是有 \(n-k\) 列有棋子,所以就是 \({n\choose {n-k}}{n\brace {n-k}} (n-k)!\)

posted @ 2023-07-03 22:38  cc0000  阅读(28)  评论(0编辑  收藏  举报