75pts求Hack
查看原帖
75pts求Hack
589961
steambird楼主2024/10/21 17:48

WA on #10 ~ #15, #17,求 Hack


大致思路:

  • 如果存在一个点,youyou 不能操作,则 tetris
  • 如果 yy 不能操作任何点,则 cont
  • 否则,只有当 youyou 一次操作的范围可以覆盖所有 yy 可操作范围时,答案为 cont,否则为 tetris(原因是,如果不能覆盖,则 yy 总是可以一次操作毁掉(染成蓝色)某个已经染成红色的段)。

考虑用滑动窗口预处理所有长度为 c2c_2 的区间从而求出 yy 的可操作范围。

目前的情况read c, expected t,即遗漏 tetris 的情况。

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <queue>
#include <cassert>
using namespace std;

inline void train() {
	   ios::sync_with_stdio(false);
	   cin.tie(0);
	   cout.tie(0);
}

typedef long long llt;

#define __int128 llt

//#define __int128 int

__int128 maxi(__int128 a, __int128 b) {
	return a > b ? a : b;
}

__int128 mini(__int128 a, __int128 b) {
	return a < b ? a : b;
}

#define lch (root<<1)
#define rch ((root<<1)|1)
#define mids() int mid = (lrange[root] + rrange[root]) >> 1
#define s_mids() int mid = (slrange[root] + srrange[root]) >> 1
#define lcall lch, maxi(lrange[root], l), mini(mid, r)
#define s_lcall lch, maxi(slrange[root], l), mini(mid, r)
#define rcall rch, maxi(mid+1, l), mini(rrange[root], r)
#define s_rcall rch, maxi(mid+1, l), mini(srrange[root], r)

constexpr int N = 8e5+4, NS = 5e6+3;
int lrange[NS], rrange[NS], slrange[NS], srrange[NS];
__int128 vals[NS], lazy[NS], az[N], single_va[NS];
long long a[N];
int n,q;
long long c1,c2,w1,w2;
queue<long long> qv;
__int128 wnd_total = 0;

__int128 tarray[NS];

int lowbit(int x) {
	return x & (-x);
}

__int128 t_query(int x) {
	if (x < 0) return 0;
	__int128 ans = 0;
	while (x) {
		ans += tarray[x];
		x ^= lowbit(x);
	}
	return ans;
}

void t_update(int x, __int128 val) {
	if (x < 0) return;
	while (x < NS) {
		tarray[x] += val;
		x += lowbit(x);
	}
}

void pushup(int root) {
	vals[root] = maxi(vals[lch], vals[rch]);
}

void build(int root, int l, int r) {
//	cerr << "build(" << root << "," << l << "," << r << ")\n";
	if (l > r) return;
	lrange[root] = l;
	rrange[root] = r;
	if (l == r) {
		vals[root] = az[l];
		return;
	}
	mids();
	build(lch, l, mid);
	build(rch, mid+1, r); 
	pushup(root);
}

int length(int root) {
	return rrange[root] - lrange[root] + 1;
}

void modify(int root, __int128 value) {
	vals[root] += value;
	lazy[root] += value;
}

void pushdown(int root) {
	modify(lch, lazy[root]);
	modify(rch, lazy[root]);
	lazy[root] = 0;
}

void update(int root, int l, int r, __int128 value) {
	if (l > r) return;
	if (lrange[root] >= l && rrange[root] <= r) {
		modify(root, value);
		return;
	}
	pushdown(root);
	mids();
	update(lcall, value); update(rcall, value);
	pushup(root);
}

void s_pushup(int root) {
	single_va[root] = maxi(single_va[lch], single_va[rch]);
}

void s_build(int root, int l, int r) {
	if (l > r) return;
	slrange[root] = l;
	srrange[root] = r;
	if (l == r) {
		single_va[root] = a[l];
		return;
	}
	s_mids();
	s_build(lch, l, mid);
	s_build(rch, mid + 1, r);
	s_pushup(root);
}

void s_update(int root, int pos, __int128 value) {
	if (slrange[root] == srrange[root]) single_va[root] += value;
	else {
		s_mids();
		if (pos <= mid) {
			s_update(lch, pos, value);
		}
		else {
			s_update(rch, pos, value);
		}
		s_pushup(root);
	}
}

__int128 s_query(int root, int l, int r) {
	if (l > r) return 0;
	if (slrange[root] >= l && srrange[root] <= r) return single_va[root];
	pushdown(root);
	s_mids();
	return maxi(s_query(s_lcall), s_query(s_rcall));
}

int _sid;

int lookup_first(int root, int l, int r, long long thr) {
	if (l > r) return 0;
	if (lrange[root] == rrange[root]) {
//		if (_sid == 1174) cerr << "left-lookup " << lrange[root] << endl;
		if (vals[root] >= thr) return lrange[root];
		else return 0;
	}
	pushdown(root);
	mids();
	if (lrange[root] >= l && rrange[root] <= r) {
		if (vals[lch] >= thr) return lookup_first(lcall, thr);
		return lookup_first(rcall, thr);
	}
	int lfind = lookup_first(lcall, thr);
	if (lfind == 0) return lookup_first(rcall, thr);
	else return lfind;
}

int lookup_last(int root, int l, int r, long long thr) {
	if (l > r) return 0;
	if (lrange[root] == rrange[root]) {
//		return lrange[root];
//		if (_sid == 1174) cerr << "right-lookup " << lrange[root] << endl;
		if (vals[root] >= thr) return lrange[root];
		else return 0;
	}
	pushdown(root);
	mids();
	if (lrange[root] >= l && rrange[root] <= r) {
		if (vals[rch] >= thr) return lookup_last(rcall, thr);
		return lookup_last(lcall, thr);
	}
	int rfind = lookup_last(rcall, thr);
	if (rfind == 0) return lookup_last(lcall, thr);
	else return rfind;
} 

int main() {
	
	//freopen("seq4.in", "r", stdin);
	//freopen("seq4.out.txt", "w", stdout);

	train();
	
	cin>>n>>q>>c1>>c2>>w1>>w2;
	for (int i = 1; i <= n; i++) {
		cin>>a[i];
		t_update(i, a[i]);
	}
	for (int i = 1; i <= c2 && i <= n; i++) {
		qv.push(a[i]);
		wnd_total += a[i];
	}
	az[1] = wnd_total;
	for (int i = c2+1; i <= n; i++) {
		// Remove sth.
		wnd_total -= qv.front();
		qv.pop();
		wnd_total += a[i];
		qv.push(a[i]);
		az[i-c2+1] = wnd_total; 
	}
	build(1, 1, n-c2+1);
	s_build(1, 1, n);
	for (int qs = 0; qs < q; qs++) {
		
		_sid = qs;
		
		int opt;
		long long x,y;
		cin>>opt>>x>>y;
		if (opt == 1) {
			update(1, maxi(1, x-c2+1), x, y);
			t_update(x, y);
			s_update(1, x, y);
		} else {
			if (s_query(1, x, y) > w1) {
				cout << "tetris\n";
				continue;
			}
			if (y-x+1 <= c2) {
				
				__int128 sequence = t_query(y) - t_query(x-1);
				if (sequence > w2) {
					if (sequence > w1 || (y-x+1) > c1) {
						cout<<"tetris\n";
					} else {
						cout<<"cont\n";
					}
				} else {
					cout<<"cont\n";
				}
				
			} else {
				//cout << "[" << x << "," << (y-c2+1) << "] -> ";
				int earliest = lookup_first(1, x, y-c2+1, w2);
				int latest = lookup_last(1, x, y-c2+1, w2);
				
				if (earliest == 0 || latest == 0) {
				 	if (earliest != 0 || latest != 0) {
				 		cerr << "error: unexpected " << earliest << "," << latest << endl; 
				 		cerr << "when querying " << x << "," << (y-c2+1) << endl;
				 		cerr << "id " << qs << endl;
				 		return 114514;
				 	}
					cout<<"cont\n";
					continue;
				}
				
				// [earliest, latest+c2-1] should be overridden.
				// cout << "[" << earliest << "," << latest << "] ";
				if (latest - earliest + 1 > c1) {
					cout<<"tetris\n";
					continue;
				}
				__int128 sequence = t_query(latest+c2-1) - t_query(earliest-1); 
				if (sequence > w1) {
					cout<<"tetris\n";
				} else {
					cout<<"cont\n";
				}
				
			}
		}
	}
	
	cout<<flush;

	return 0;
}
2024/10/21 17:48
加载中...