2022.9.15———HZOI【CSP-S开小灶4】游寄

Preface

Rank31/39

20pts+0pts=20pts

最近出现了暴力不会打的情况

我震惊

我tm暴力不会打?

然后其实仔细思考也是可以打的。只要暴力不是dp。但是赛时我老是懒。。。

T1 山洞,T2 beauty

T1 

Ayaka讲的,我竟然听懂了

首先考虑这样一个事情,走长度为1和走长度为n+1长是否等同?

答案是显然等同。因为要对n取模,这是个环好吧。

再思考,假设我从x位置走a长度到y位置,然后再从yb长度到x位置,从x走到x方案数是不是要加上第一个过程的方案数×第二个过程的方案数?

这就有点神奇了

我谔谔。

仔细一想,他为什么不对呢?

第一个过程和第二个过程有冲突吗?没有。

因此他满足乘法原理。

做一件事,完成它需要分成n个步骤,做第一 步有m1种不同的方法,做第二步有m2种不同的方法,……,做第n步有mn种不同的方法。那么完成这件事共有 N=m1×m2×m3××mn 种不同的方法。 和加法原理是数学概率方面的基本原理。———度娘

AB独立时,乘法原理适用。———me

然后思路就比较明确了,首先处理出前n次的dp,然后用f[n][i]去转移,注意是第n项,然后用n去转移2n等等,二进制拆分指数,矩阵快速幂即可(矩阵快速幂第n项)。

然后最后可能会有剩余,因为m不一定被n整除,此时最后还需要暴力dp一下。

T1
#include <iostream>
#include <cstring>
#define GMY (520&1314)
#define FBI_OPENTHEDOOR(x) freopen(#x ".in", "r", stdin), freopen(#x ".out", "w", stdout);
#define re register int
#define char_phi signed
#define MARK cout << "###"
#define MARKER "@@@"
#define LMARK "!!!~~~"
#define ZY " qwq "
#define _ ' '
#define Endl cout << '\n'
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define N 1005
#define M 1000000002
#define mod %
#define P 1000000007
using namespace std;
inline void Fastio_setup(){ios::sync_with_stdio(false); cin.tie(NULL), cout.tie(NULL), cerr.tie(NULL);}
/*
	Ayaka确实强
	处理出来走前n步的方案都是些啥
	考虑这个
	设两个数组都是走x步的(其实是同一个数组),那么:走2x步到位置place 就等同于 先走x步到另一个位置 再走x步到达位置place
	所以就可以枚举这个走x步的时候,第一个数组所在位置,第二个数组所在位置,然后直接相乘转移到2x步的位置(乘法原理)
	然后就可以跑矩阵快速幂了,m/n
	因为走n+1步就等同于走1步,所以就可以先预处理f[n][n],不过矩阵快速幂的时候只会用上f[n][1~n]
	最后因为n不一定整除m,所以最后要再暴力dp一下,也就是f[floor(m/n)*n] * f[m%n] -> f[m]
*/
int n, m;
long long a[N], tmp[N], res[N];
long long f[N][N];
/*
	inline long long ksm(long long A, long long B){// normal
		long long res(1);
		while (B != 0){
			if ((B & 1) == 1) res = res * A mod P;
			A = A * A mod P;
			B >>= 1;
		}
		return res;
	}
*/
inline void workres(){
	memset(tmp, 0, sizeof(tmp));
	for (re i = 0 ; i < n ; ++ i)
		for (re j = 0 ; j < n ; ++ j)// 两个n合成一个2n
			tmp[(i+j) mod n] = (tmp[(i+j) mod n] + res[i] * a[j] mod P) mod P;
	for (re i = 0 ; i < n ; ++ i)
		res[i] = tmp[i];
}
inline void worka(){
	memset(tmp, 0, sizeof(tmp));
	for (re i = 0 ; i < n ; ++ i)
		for (re j = 0 ; j < n ; ++ j)
			tmp[(i+j) mod n] = (tmp[(i+j) mod n] + a[i] * a[j] mod P) mod P;
	for (re i = 0 ; i < n ; ++ i)
		a[i] = tmp[i];
}
inline void ksm(long long B){
	while (B != 0){
		if ((B & 1) == 1) workres();
		worka();
		B >>= 1;
	}
}
void work(){
	cin >> n >> m;
	f[1][1] = f[1][n-1] = 1;// 从0往右、往左
	for (re i = 2 ; i <= n ; ++ i){
		for (re j = 0 ; j < n ; ++ j){
			if ((j-i+n) mod n != (j+i) mod n)// 我超!去重!我说我大样例咋没过嘞
				f[i][j] = (f[i-1][(j-i+n) mod n] + f[i-1][(j+i) mod n]) mod P;
			else 
				f[i][j] = f[i-1][(j+i) mod n];
		}
	}
	for (re i = 0 ; i < n ; ++ i)
		a[i] = f[n][i];
	res[0] = 1;// 相当于直接把a转移过来
	ksm(m/n); m %= n;
	if (m != 0){
		for (re i = 0 ; i < n ; ++ i)
			a[i] = f[m][i];
		workres();
	}
	cout << res[0] << '\n';	
}
// #define IXINGMY
char_phi main(){
    #ifdef IXINGMY
        FBI_OPENTHEDOOR(a);
    #endif
    Fastio_setup();
    work();
    return GMY;
}

T2 beauty

树的重心弔题

好像是某种构造,我没学

T2
#include <iostream>
#define GMY (520&1314)
#define FBI_OPENTHEDOOR(x) freopen(#x ".in", "r", stdin), freopen(#x ".out", "w", stdout);
#define re register int
#define char_phi signed
#define MARK cout << "###"
#define MARKER "@@@"
#define LMARK "!!!~~~"
#define ZY " qwq "
#define _ ' '
#define Endl cout << '\n'
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define N 100005
#define KKK 30005
using namespace std;
inline void Fastio_setup(){ios::sync_with_stdio(false); cin.tie(NULL), cout.tie(NULL), cerr.tie(NULL);}
int n, K, whatsthis, star_cnt, final_ans;
char is[N];
int head[N], sz[N];
struct star{int v, nxt;} e[N<<1];
inline void star_add(int u, int v){e[++ star_cnt].v=v, e[star_cnt].nxt=head[u], head[u]=star_cnt;}
void dfs(int x, int faer){
	if (is[x] == true)
		sz[x] = 1;
	for (re i = head[x] ; i ; i = e[i].nxt){
		int v = e[i].v;
		if (v == faer)
			continue;
		dfs(v, x);
		sz[x] += sz[v];
		final_ans += MIN(sz[v], K - sz[v]);
	}
}
void work(){
	cin >> n >> K >> whatsthis; K *= 2;
	for (re i = 1, who ; i <= K ; ++ i)
		{cin >> who; is[who] = true;}
	for (re i = 1, uu, vv ; i <= n-1 ; ++ i)
		{cin >> uu >> vv; star_add(uu, vv), star_add(vv, uu);}
	dfs(1, 0);
	cout << final_ans << '\n';
}
// #define IXINGMY
char_phi main(){
    #ifdef IXINGMY
        FBI_OPENTHEDOOR(a);
    #endif
    Fastio_setup();
    work();
    return GMY;
}
posted @   char_phi  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示