WA on #10 ~ #15, #17,求 Hack
大致思路:
tetris。cont。cont,否则为 tetris(原因是,如果不能覆盖,则 yy 总是可以一次操作毁掉(染成蓝色)某个已经染成红色的段)。考虑用滑动窗口预处理所有长度为 c2 的区间从而求出 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;
}