首页 > 其他分享 >AtCoder Beginner Contest 334 G Christmas Color Grid 2

AtCoder Beginner Contest 334 G Christmas Color Grid 2

时间:2023-12-24 11:23:31浏览次数:33  
标签:AtCoder typedef Beginner Contest int ll maxm define

洛谷传送门

AtCoder 传送门

考虑相当于把每个标记点的边全部断掉,然后求连通块个数。

考虑一条边 \((u, v)\)(设 \(u < v\))的出现时间,不难发现是 \([1, u - 1] \cup [u + 1, v - 1] \cup [v + 1, n]\)。于是考虑直接套线段树分治和可撤销并查集。

时空复杂度均为 \(O(n^2 \log n)\)。实现得别太随意就能过了。

code
// Problem: G - Christmas Color Grid 2
// Contest: AtCoder - UNIQUE VISION Programming Contest 2023 Christmas (AtCoder Beginner Contest 334)
// URL: https://atcoder.jp/contests/abc334/tasks/abc334_g
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define ID(x, y) (((x) - 1) * m + (y))
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<int, int> pii;

const int maxn = 1010;
const int maxm = 1000100;
const ll mod = 998244353;

inline ll qpow(ll b, ll p) {
	ll res = 1;
	while (p) {
		if (p & 1) {
			res = res * b % mod;
		}
		b = b * b % mod;
		p >>= 1;
	}
	return res;
}

ll n, m, ans;
char s[maxn][maxn];
bool vis[maxm];
vector<int> G[maxm];

int fa[maxm], rnk[maxm], t, top;
pair<int*, int> stk[maxm * 10];

int find(int x) {
	return fa[x] == x ? x : find(fa[x]);
}

inline void merge(int x, int y) {
	x = find(x);
	y = find(y);
	if (x == y) {
		return;
	}
	stk[++top] = mkp(&t, t);
	--t;
	if (rnk[x] <= rnk[y]) {
		stk[++top] = mkp(fa + x, fa[x]);
		fa[x] = y;
		if (rnk[x] == rnk[y]) {
			stk[++top] = mkp(rnk + y, rnk[y]);
			++rnk[y];
		}
	} else {
		stk[++top] = mkp(fa + y, fa[y]);
		fa[y] = x;
	}
}

inline void undo() {
	*stk[top].fst = stk[top].scd;
	--top;
}

vector<pii> T[2100000];

void update(int rt, int l, int r, int ql, int qr, pii x) {
	if (ql > qr) {
		return;
	}
	if (ql <= l && r <= qr) {
		T[rt].pb(x);
		return;
	}
	int mid = (l + r) >> 1;
	if (ql <= mid) {
		update(rt << 1, l, mid, ql, qr, x);
	}
	if (qr > mid) {
		update(rt << 1 | 1, mid + 1, r, ql, qr, x);
	}
}

void dfs(int rt, int l, int r) {
	int lst = top;
	for (pii p : T[rt]) {
		merge(p.fst, p.scd);
	}
	if (l == r) {
		if (!vis[l]) {
			ans = (ans + t - 1) % mod;
		}
	} else {
		int mid = (l + r) >> 1;
		dfs(rt << 1, l, mid);
		dfs(rt << 1 | 1, mid + 1, r);
	}
	while (top > lst) {
		undo();
	}
}

void solve() {
	scanf("%lld%lld", &n, &m);
	t = n * m;
	for (int i = 1; i <= n * m; ++i) {
		fa[i] = i;
	}
	for (int i = 1; i <= n; ++i) {
		scanf("%s", s[i] + 1);
	}
	int c0 = 0, c1 = 0;
	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= m; ++j) {
			if (s[i][j] == '.') {
				vis[ID(i, j)] = 1;
				++c0;
				continue;
			}
			++c1;
			if (i < n && s[i + 1][j] == '#') {
				G[ID(i, j)].pb(ID(i + 1, j));
			}
			if (j < m && s[i][j + 1] == '#') {
				G[ID(i, j)].pb(ID(i, j + 1));
			}
		}
	}
	for (int i = 1; i <= n * m; ++i) {
		for (int j : G[i]) {
			update(1, 1, n * m, 1, i - 1, mkp(i, j));
			update(1, 1, n * m, i + 1, j - 1, mkp(i, j));
			update(1, 1, n * m, j + 1, n * m, mkp(i, j));
		}
	}
	dfs(1, 1, n * m);
	printf("%lld\n", (ans * qpow(c1, mod - 2) + mod - c0) % mod);
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:AtCoder,typedef,Beginner,Contest,int,ll,maxm,define
From: https://www.cnblogs.com/zltzlt-blog/p/17924182.html

相关文章

  • AtCoder Beginner Contest 334
    A-ChristmasPresent(abc334A)题目大意给定两个数\(b,g(b\neqg)\),如果\(b\)大则输出Bat,否则输出Glove。解题思路比较大小输出即可。神奇的代码#include<bits/stdc++.h>usingnamespacestd;usingLL=longlong;intmain(void){ios::sync_with_stdio(f......
  • AtCoder 杂题精选(2023 年末)
    [ABC324G]GenerateArrays第一次知道AtCoder还有这种数据结构题。首先,所谓的“切分序列”是假,实际上只需要记录每个操作后,具体取到的原始数组的值域、下标域是什么。对于给定的下标域,求值域内数的个数,可以使用可持久化线段树,很类似区间第\(k\)大数的思路。对于操作一,考虑......
  • P9361 [ICPC2022 Xi'an R] Contests
    更好的阅读体验P9361[ICPC2022Xi'anR]Contests首先观察一下性质,每个\(l\)在每场比赛里一定是对应着某个前缀。发现题目要求的是最小的满足要求的\(l\),最暴力的大概是维护五个指针,每次答案\(+1\),然后尝试跳一步,什么时候某个前缀包含了\(x\)当前的计数器就是答案。考......
  • The 1st Universal Cup. Stage 0: Nanjing (Trial Contest)
    比赛链接题面懒得写了。A.Stop,YesterdayPleaseNoMore袋鼠移动相当于边界和洞移动。通过模拟可以得出:不考虑洞,移动后剩余袋鼠的矩形。以及假设洞在原点,移动后形成的轨迹形状。枚举洞在哪个位置,多干掉的袋鼠就是两个几何图形的交。由于洞的移动轨迹较复杂,我们考虑让它不动......
  • AtCoder Beginner Contest 333
    title:categories:算法题解description:tags:-atcoder-DFS-思维-贪心-差分-概率DP-连分数cover:/img/chino/vec/chino56.jpgkatex:truedate:2023-12-2114:47:38A-ThreeThrees(abc333A)题目大意给定一个\(0-9\)的数\(n\),输出这......
  • 【misc】[HNCTF 2022 WEEK2]calc_jail_beginner_level4.1(JAIL) --沙盒逃逸,python模板
    这道题没给附件,直接连上看看这里一开始用().__class__.__base__.__subclasses__()[-4].__init__.__globals__[bytes([115,121,115,116,101,109]).decode()](bytes([115,104]).decode())进行尝试,后面发现bytes函数被禁用了,可以用另外的函数代替().__class__.__base__.__subclasse......
  • AtCoder_abc333
    AtCoder_abc333比赛链接A-ThreeThrees题目描述输入一个\(N\)输出\(N\)个\(N\)。解题思路(这个题但凡学过都能写出来吧)Code//Problem:A-ThreeThrees//Contest:AtCoder-ToyotaProgrammingContest2023#8(AtCoderBeginnerContest333)//URL:https://a......
  • 【misc】[HNCTF 2022 WEEK2]calc_jail_beginner_level4(JAIL) --沙盒逃逸,python模板注
    查看附件信息这里禁用了__import__,直接导致了help()函数和breakpoint()函数没法使用,并且还过滤了关键字符,这里考虑python模板注入,但是这里还过滤chr(),这里可以使用bytes函数payload如下:().__class__.__base__.__subclasses__()[-4].__init__.__globals__['system']('sh')......
  • AtCoder 333 A-D
    AThreeThrees(打表importjava.util.*;classMain{publicstaticvoidmain(String[]args){Scannersc=newScanner(System.in);intn=sc.nextInt();if(n==1)System.out.println(1);if(n==2)System.out.println......
  • AtCoder Beginner Contest 333
    B-Pentagon难度:⭐题目大意给定一个正五边形,其顶点为ABCDE;给定端点a,b,c,d;问a,b之间的距离和c,d之间的距离是否相等;解题思路两个端点之间的距离就看两个端点之间隔了几条边就行;并且因为是五边形,隔x条边和隔5-x条边是等价的;神秘代码#include<bits......