国庆集训 1107-1108(未完成)

在这里插入图片描述

抛硬币coin

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const ll mod = 998244353;
inline ll M(ll a){return a%mod;}
inline ll add(ll a, ll b){return M(a+b);}
inline ll mul(ll a, ll b){return M(a*b);}
inline ll sub(ll a, ll b){return M(a-b+mod);}
ll P(ll a, ll b){ll c=1;while(b){if(b&1)c=M(c*a);b>>=1;a=M(a*a);}return c;}
ll n, ans;

int main() {
	scanf("%lld", &n);
	if(n&1) ans = add(3, P(P(3, mod-2), n-1));
	else    ans = sub(3, P(P(3, mod-2), n-1));
	printf("%lld", mul(ans, P(6, mod-2)));
	return 0;
}

在这里插入图片描述
在这里插入图片描述

摧毁树状图 sabotage

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

qt大佬的题解

在这里插入图片描述
在这里插入图片描述

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int N = 1e5;
const ll mod = 998244353;

ll size[N], f[N][210][2], g[510][2], lin[N], len, n, m;
inline void C(){memset(g, 0, sizeof g);}
struct psx{int next, y;} e[N<<1];

inline ll M(ll a){return a%mod;}
inline ll add(ll a, ll b){return M(a+b);}
inline ll mul(ll a, ll b){return M(a*b);}
inline ll sub(ll a, ll b){return M(a-b+mod);}
ll P(ll a, ll b){ll c=1;while(b){if(b&1)c=M(c*a);b>>=1;a=M(a*a);}return c;}
//取模套餐

inline void insert(int xx, int yy) {
	e[++len].next = lin[xx];
	lin[xx] = len;
	e[len].y = yy;
}

inline void dfs(int x, int fa) {
	size[x] = f[x][0][0] = 1;
	for(int i = lin[x]; i; i = e[i].next) {
		int y = e[i].y;
		if(y == fa) continue;
		dfs(y, x); C();
		for(int j = 0; j <= size[x]; j++)
		for(int k = 0; k <= size[y]; k++) {
			g[j+k][0] = add(g[j+k][0], mul(f[x][j][0], f[y][k][0]));
			g[j+k][0] = add(g[j+k][0], mul(2, mul(f[x][j][0], f[y][k][1])));
			g[j+k][1] = add(g[j+k][1], mul(2, mul(add(f[y][k][0], f[y][k][1]), f[x][j][1])));
			g[j+k+1][1] = add(g[j+k+1][1], mul(f[x][j][0], f[y][k][0]));
		}//子树转移
		for(int j = 0; j < m; j++) {
			f[x][j][0] = add(g[j][0], g[j+m][0]);
			f[x][j][1] = add(g[j][1], g[j+m][1]);
		}//合并转移
		size[x] = min(add(size[x], size[y]), 1LL*m);//时间优化
	}
}

int main() {
	scanf("%lld%lld", &n, &m);
	for(int i = 1, u, v; i < n; i++) {
		scanf("%d%d", &u, &v);
		insert(u, v);
		insert(v, u); 
	}
	dfs(1, 0);
	printf("%lld\n", M(f[1][0][0] + f[1][0][1]));
	return 0;
}

在这里插入图片描述
在这里插入图片描述

逃出生天escape

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

考场50分代码 策略不完全 但意外RP高
#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int N = 2e6;
const int M = 1e3+10;
char ch[M];
int n, m, end1, end2, head=1, tail=0;
int f[N], q[N], p[N], e[N][10], a[M][M];
int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};

inline int C(int i, int j) {return i*(m+2)+j;}
inline int Si(int i){return i/(m+2);}
inline int Sj(int i){return i%(m+2);}
inline bool Pn(int i){return 0<=i&&i<=n+1 ? 1 : 0;}
inline bool Pm(int i){return 0<=i&&i<=m+1 ? 1 : 0;}
inline bool check(int i, int j){return (i==end1 && j==end2) ? 1 : 0;}

inline int bfs() {
	while(head <= tail) {
		int k = q[head], val = p[head++], x = Si(k), y = Sj(k);
		if(Pn(x) && Pm(y+1) && !f[C(x, y+1)] && a[x][y+1]) {
			f[C(x, y+1)] = val+1;
			if(check(x, y+1)) return val+1;
			else q[++tail] = C(x, y+1), p[tail] = val+1;
		}//右边 
		if(Pn(x) && Pm(y-1) && !f[C(x, y-1)] && a[x][y-1]) {
			f[C(x, y-1)] = val+1;
			if(check(x, y-1)) return val+1;
			else q[++tail] = C(x, y-1), p[tail] = val+1;
		}//左边 
		if(Pn(x-1) && Pm(y) && !f[C(x-1, y)] && a[x-1][y]) {
			f[C(x-1, y)] = val+1;
			if(check(x-1, y)) return val+1;
			else q[++tail] = C(x-1, y), p[tail] = val+1;
		}//上边 
		if(Pn(x+1) && Pm(y) && !f[C(x+1, y)] && a[x+1][y]) {
			f[C(x+1, y)] = val+1;
			if(check(x+1, y)) return val+1;
			else q[++tail] = C(x+1, y), p[tail] = val+1;
		}//下边
		for(int i = 1; i <= 4; i++) {
			int x = Si(e[k][i]), y = Sj(e[k][i]);
			if(Pn(x) && Pm(y) && !f[C(x, y)] && a[x][y]) {
				f[C(x, y)] = val+1; 
				if(check(x, y)) return val+1;
				else q[++tail] = C(x, y), p[tail] = val+1;
			}
		} 
		if(head == 2) f[k] = M;
	}
}

int main() {
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; i++) {
		scanf("%s", ch+1);
		for(int j = 1; j <= m; j++) {
			if(ch[j] == '#') a[i][j] = 0;
			else a[i][j] = -1;
			if(ch[j] == 'C') end1 = i, end2 = j;
			if(ch[j] == 'S') q[++tail] = C(i, j); 
		}
	}
	for(int i = 0; i <= n+1; i++) 
	for(int j = 0; j <= m+1; j++) 
	if(!a[i][j]) 
		for(int k = 0; k < 4; k++) {
			int x = i+(dx[k]<<1), y = j+(dy[k]<<1);
			while(Pn(x) && Pm(y) && a[x][y] && a[i+dx[k]][j+dy[k]]) {
				e[C(x, y)][k+1] = C(i+dx[k], j+dy[k]);
				x += dx[k], y += dy[k];
			}
		}
	printf("%d", bfs());
	return 0;
}

正解 迪杰斯特拉
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e3+10;
int n, m, len, st, ed;
int l[N][N], r[N][N], u[N][N], d[N][N], lin[N * N], a[N][N];
int v[N*N], dis[N*N];
char ch[N];
struct psx{ int next, y, v; }e[N*N<<3];

inline void add(int xx, int yy, int vv) {
	e[++len].next = lin[xx];
	e[len].y = yy;
	e[len].v = vv;
	lin[xx] = len;
}

inline int C(int i, int j) {return (i-1)*m+j;}
inline int Min(int i, int j){return i<j ? i : j;}

inline void prep() {
	for (int i = 1; i <= n; i++) {
		l[i][0] = 0;
		for (int j = 1; j <= m; j++)
			l[i][j] = !a[i][j] ? j : l[i][j-1];
		r[i][m+1] = m+1;
		for (int j = m; j >= 1; j--)
			r[i][j] = !a[i][j] ? j : r[i][j+1];
	}
	for (int j = 1; j <= m; j++) {
		u[0][j] = 0;
		for (int i = 1; i <= n; i++)
			u[i][j] = !a[i][j] ? i : u[i-1][j];
		d[n+1][j] = n+1;
		for (int i = n; i >= 1; i--)
			d[i][j] = !a[i][j] ? i : d[i+1][j];
	}
}
inline void edge() {
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++) {
			if (!a[i][j]) continue;
			if (i+1<=n && a[i+1][j]) {
				add(C(i, j), C(i+1, j), 1);
				add(C(i+1, j), C(i, j), 1);
			}
			if (j+1<=m && a[i][j+1]) {
				add(C(i, j), C(i, j+1), 1);
				add(C(i, j+1), C(i, j), 1);
			}
		}
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++) {
			if (!a[i][j]) continue;
			int dl = j - l[i][j];
			int dr = r[i][j] - j;
			int du = i - u[i][j];
			int dd = d[i][j] - i;
			int dis = Min(Min(dl, dr), Min(du, dd));
			if (l[i][j] != j-1) add(C(i, j), C(i, l[i][j]+1), dis);
			if (r[i][j] != j+1) add(C(i, j), C(i, r[i][j]-1), dis);
			if (u[i][j] != i-1) add(C(i, j), C(u[i][j]+1,j), dis);
			if (d[i][j] != i+1) add(C(i, j), C(d[i][j]-1,j), dis);
		}
}
inline int dijkstra() {
	memset(dis, 0x3f, sizeof dis);
	priority_queue < pair <int, int> > q;
	q.push(make_pair(0, st));
	dis[st] = 0;
	while (q.size()) {
		int x = q.top().second; q.pop();
		if (v[x]) continue; v[x] = 1;
		if (x == ed) return dis[x];
		for (int i = lin[x], y=e[i].y; i; i = e[i].next, y = e[i].y)
			if (dis[x] + e[i].v < dis[y]) {
				dis[y] = dis[x] + e[i].v;
				q.push(make_pair(-dis[y], y));
			}
	}
	return -1;
}

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++) {
		scanf("%s", ch + 1);
		for (int j = 1; j <= m; j++) {
			if(ch[j] == '#') a[i][j] = 0;
			else a[i][j] = 1;
			if (ch[j] == 'S') st = C(i, j);
			if (ch[j] == 'C') ed = C(i, j);
		}
	} 
	prep();
	edge();
	printf("%d\n", dijkstra());
	return 0;
}
	

在这里插入图片描述
在这里插入图片描述

走步 travel

在这里插入图片描述
在这里插入图片描述
我对不起我的数学老师……余弦定理的经典应用,哎!
在这里插入图片描述
在这里插入图片描述
B B B点为原点,那么第一次操作后第一点必然在圆 B B B上,设为点 A A A
同理第二次操作,必然在圆 A A A上,设为点 C C C,设角度为 θ \theta θ
那么利用余弦定理, B C BC BC 2 ^{2} 2 = A C AC AC 2 ^{2} 2 + A B AB AB 2 ^{2} 2 - 2 2 2 ∗ * A B AB AB ∗ * A C AC AC ∗ * c o s cos cos θ \theta θ
——> B C BC BC 2 ^{2} 2 = 2 2 2 - 2 2 2 ∗ * c o s cos cos θ \theta θ
在这里插入图片描述
已知余弦函数如上图,显然可得平均值为0,所以式子答案为 2 2 2
同理可做 3 3 3 4 4 4、……
在这里插入图片描述

#include<bits/stdc++.h>
#define ll long long
using namespace std;

int main(){ 
	int n;
	scanf("%d", &n);
	printf("%d\n", n);
	return 0;
}

在这里插入图片描述
在这里插入图片描述

遥不可及far

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

考场60分超时代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int N = 1e5+10;
struct psx{int l, r, i, ans;} Q[N];
inline bool mycmp1(psx a, psx b){return a.r==b.r ? a.l>b.l : a.r>b.r;}
inline bool mycmp2(psx a, psx b){return a.i<b.i;}
vector<int> b[N];
int n, m, Qi, a[N];
bool c[N];

inline int Max(int a, int b){return a<b ? b : a;}

inline void init() {
	scanf("%d%d%d", &n, &m, &Qi);
	for(int i = 1; i <= n; i++) {
		scanf("%d", &a[i]);
		b[a[i]].push_back(i);
		c[a[i]] = 1;
	}
	for(int i = 1; i <= Qi; i++) {
		scanf("%d%d", &Q[i].l, &Q[i].r);
		Q[i].i = i;
	}
	sort(Q+1, Q+1+Qi, mycmp1);
}

inline void work() {
	int len, num1, num2;
	for(int i = 1; i <= Qi; i++) 
	for(int j = 1; j <= m; j++) 
	if(c[j]) {
		len = b[j].size(), num1=0, num2=0;
		for(int k = len-1; k >= 0 && c[j]; k--) {
			while(b[j][k] > Q[i].r) {
				b[j].pop_back();
				len--; if(!len) c[j] = 0;
				k--;
			}
			if(Q[i].l <= b[j][k] && b[j][k] <= Q[i].r) {
				if(!num1) num1 = b[j][k];
				else num2 = b[j][k];
			}
			if(Q[i].l > b[j][k]) break;
		}
		if(num1 && num2) Q[i].ans = Max(Q[i].ans, num1-num2);
	}
}

inline void outo() {
	sort(Q+1, Q+1+Qi, mycmp2);
	for(int i = 1; i <= Qi; i++)
		printf("%d\n", Q[i].ans);
}
int main() {
	init();
	work();
	outo();
	return 0;
}
神奇暴力做法(还有莫队回滚的AC,就不写啦)
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5+10;
int n, m, q, l, r, a[N], ans;
int main() {
	scanf("%d%d%d", &n, &m, &q);
	for (int i = 1; i <= n; i++)
		scanf("%d", &a[i]);
	while (q--) {
		scanf("%d%d", &l, &r);
		ans = 0;
		for (int j = r - l; j; j--) {
			for (int k = l; k + j <= r; k++)
			if (a[k + j] == a[k]) { ans = j; break; } 
			if (ans) break;
		}
		printf("%d\n", ans);
	}
	return 0;
}

在这里插入图片描述
在这里插入图片描述

颠倒黑白rev

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值