萌新求助线段树板子题
查看原帖
萌新求助线段树板子题
576817
Lyrella楼主2024/11/6 11:18

思路就是设 sis_i 表示时间为 ii 时有多少黑点的左边和上边没有黑点,tit_i 表示时间为 ii 时有多少白点相邻的黑点数大于1,维护 si+tis_i+t_i 的最小值和最小值个数。没加修改操作前萌新的输出无误,但是加上后就错了,样例都没过,实在是调不出来力/ll,求好哥哥帮助qwq

#define LOCAL
#include <bits/stdc++.h>
#define ll long long
#define db double
#define ld long double
#define pii pair < int , int >
#define mkp make_pair
#define fst first
#define snd second
#define pb push_back
#define sz size
#define rsz resize
#define pc putchar
#define gc getchar
#define bg begin
#define ed end

using namespace std;

namespace IO{
	#ifndef LOCAL
		#define SIZE (1 << 20)
		char buf1[SIZE], buf2[SIZE], *p1 = buf1, *p2 = buf1, *p3 = buf2;
		#define gc() (p1 == p2 && (p2 = (p1 = buf1) + fread(buf1, 1, SIZE, stdin), p1 == p2) ? EOF : *p1++)
		#define flush() (fwrite(p3 = buf2, 1, SIZE, stdout))
		#define pc(ch) (p3 == buf2 + SIZE && flush(), *p3++ = (ch))
		class Flush{public : ~ Flush(){flush();}}_;
	#endif
	template < typename type >
	inline void rd(type &x){
		x = 0; bool f(0); char c = gc();
		while(! isdigit(c))f ^= c == '-', c = gc();
		while(isdigit(c))x = (x << 3) + (x << 1) + (c ^ 48), c = gc();
		f ? x = - x : 0;
	}
	template < typename type >
	inline void wt(type x){
		x < 0 ? x = - x, pc('-') : 0; static short st[50], top(0);
		do st[++top] = x % 10, x /= 10; while(x);
		while(top)pc(st[top--] ^ 48);
	}
	inline char rd(char &c){return c = gc();}
	inline char wt(const char &c){return pc(c);}
	template < typename type, typename ...T >
	inline void rd(type &x, T &...y){rd(x), rd(y...);}
	template < typename type, typename ...T >
	inline void wt(type x, T ...y){wt(x), pc(' '), wt(y...), sizeof ...(y) ^ 1 ? 0 : pc('\n');}
	#ifndef LOCAL
		#undef SIZE
		#undef gc
		#undef pc
		#undef flush
	#endif
}
using namespace IO;

const db eps = 1e-8;
const ll inf = 1e9;
const int N = 1e6 + 5;

int h, w, q;
vector < vector < int > > g;

struct node{
	int x, y, tim;
}a[N];

int res[N << 2], cnt[N << 2], tg[N << 2];

#define ls x << 1
#define rs x << 1 | 1

void upd(int x){
	res[x] = min(res[ls], res[rs]);
	cnt[x] = cnt[ls] * (res[x] == res[ls]) + cnt[rs] * (res[x] == res[rs]);
}
void init(int x, int l, int r){
	if(l == r)return(void)(cnt[x] = 1);
	int mid = l + r >> 1;
	init(ls, l, mid), init(rs, mid + 1, r);
	upd(x);
}
void pd(int x){
	if(! tg[x])return;
	tg[ls] += tg[x], res[ls] += tg[x];
	tg[rs] += tg[x], res[rs] += tg[x];
	return(void)(tg[x] = 0);
}
void mdf(int x, int l, int r, int ql, int qr, int y){
	if(ql <= l and r <= qr)return(void)(res[x] += y, tg[x] += y);
	int mid = l + r >> 1; pd(x);
	if(ql <= mid)mdf(ls, l, mid, ql, qr, y);
	if(mid < qr)mdf(rs, mid + 1, r, ql, qr, y);
	upd(x);
}

int get(int x, int y){
	if(x < 0 or y < 0 or x >= h or y >= w)return inf;
	return a[g[x][y]].tim;
}

void option(int i, int op){
	vector < int > lp; int t1, t2;
	lp.pb(get(a[i].x + 1, a[i].y));
	lp.pb(get(a[i].x, a[i].y + 1));
	lp.pb(t1 = get(a[i].x - 1, a[i].y));
	lp.pb(t2 = get(a[i].x, a[i].y - 1));
	sort(lp.bg(), lp.ed()); int lpos = lp[1];
	if(a[i].tim > lpos)mdf(1, 1, h * w, lpos, a[i].tim - 1, op);
	t1 = min(t1, t2); if(t1 > a[i].tim)mdf(1, 1, h * w, a[i].tim, t1 - 1, op);
}

int main(){
	rd(h, w, q); g.rsz(h); for(int i = 0; i < h; ++i)g[i].rsz(w);
	for(int i = 1; i <= h * w; ++i){
		rd(a[i].x, a[i].y);
		g[a[i].x][a[i].y] = a[i].tim = i;
	}
	init(1, 1, h * w);
	for(int i = 1; i <= h * w; ++i)option(i, 1);
	for(int i = 1, u, v; i <= q; ++i){
		rd(u, v); ++u, ++v;
		option(u, - 1), option(v, - 1);
		swap(a[u].tim, a[v].tim);
		option(u, 1), option(v, 1);
		wt(cnt[1], res[1]); //pc('\n');
	}
	return 0;
}

2024/11/6 11:18
加载中...