QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#243772 | #4940. Token Distance | ideograph_advantage# | TL | 1ms | 7720kb | C++17 | 4.5kb | 2023-11-08 17:06:44 | 2023-11-08 17:06:45 |
Judging History
answer
#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
#define iter(v) v.begin(), v.end()
#define SZ(v) (int)v.size()
#define pb emplace_back
#define ff first
#define ss second
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
#ifdef zisk
void debug(){cout << endl;}
template<class T, class ... U>
void debug(T a, U ... b){cout << a << " ", debug(b...);}
template<class T> void pary(T l, T r){
while(l != r) cout << *l << " ", l++;
cout << endl;
}
#else
#define debug(...) void()
#define pary(...) void()
#endif
template<class A, class B>
ostream& operator<<(ostream& o, pair<A, B> p){
return o << '(' << p.ff << ',' << p.ss << ')';
}
#define maxn 100005
const int inf = 1<<30;
struct segtree{
int type; //0: min, 1:max, 2:gcd
int seg[4*maxn];
void pull(int cur, int l, int r) {
if (type == 0) {
seg[cur] = min(seg[cur*2], seg[cur*2+1]);
} else if (type == 1) {
seg[cur] = max(seg[cur*2], seg[cur*2+1]);
} else {
seg[cur] = __gcd(seg[cur*2], seg[cur*2+1]);
}
}
void init(int cur, int l, int r, vector<int> a) {
if (r <= l) return;
if (r - l == 1) {
seg[cur] = a[l];
return;
}
int m = (l + r) / 2;
init(cur*2, l, m, a);
init(cur*2+1, m, r, a);
pull(cur, l, r);
}
int modify(int cur, int l, int r, int x, int v) {
if (r <= l) return 0;
if (r - l == 1) {
seg[cur] = v;
return 1;
}
int m = (l + r) / 2, cl = 0, cr = 0;
if (x < m) cl = modify(cur*2, l, m, x, v);
else cr = modify(cur*2+1, m, r, x, v);
if (cl || cr) {
int orig = seg[cur];
pull(cur, l, r);
return (seg[cur] == orig) ? 0 : 1;
}
return 0;
}
int query(int cur, int l, int r, int ql, int qr) {
if (r <= l || qr <= l || ql >= r) {
if (type == 0) return inf;
else if (type == 1) return -1;
else return 0;
}
if (ql <= l && qr >= r) return seg[cur];
int m = (l + r) / 2;
int vl = query(cur*2, l, m, ql, qr), vr = query(cur*2+1, m, r, ql, qr);
if (type == 0) return min(vl, vr);
else if (type == 1) return max(vl, vr);
else return __gcd(vl, vr);
}
} mi, ma, gc, prv; //prv: last occurence of same value
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0);
int n, q;
cin >> n >> q;
vector<int> a(n+1), d(n+1);
for (int i = 1;i <= n;i++) {
cin >> a[i];
d[i] = abs(a[i] - a[i-1]);
}
mi.type = 0, ma.type = 1, gc.type = 2;
prv.type = 1;
mi.init(1, 0, n+1, a);
ma.init(1, 0, n+1, a);
gc.init(1, 0, n+1, d);
set<pii> se;
vector<int> last(n+1, 0);
for (int i = 1;i <= n;i++) {
pii add = make_pair(a[i], i);
auto it = se.lower_bound(add);
if (it != se.begin() && (*prev(it)).ff == a[i]) {
last[i] = (*prev(it)).ss;
}
se.insert(add);
}
prv.init(1, 0, n+1, last);
while(q--) {
int type;
cin >> type;
if (type == 1) {
int x, y; cin >> x >> y;
{
auto it = se.upper_bound(make_pair(a[x], x));
auto del = prev(it);
if (it != se.end()) {
if (del != se.begin() && (*prev(del)).ff == (*it).ff) {
last[(*it).ss] = (*prev(del)).ss;
} else {
last[(*it).ss] = 0;
}
prv.modify(1, 0, n+1, (*it).ss, last[(*it).ss]);
}
se.erase(del);
}
a[x] = y;
mi.modify(1, 0, n+1, x, y);
ma.modify(1, 0, n+1, x, y);
d[x] = abs(a[x] - a[x-1]);
gc.modify(1, 0, n+1, x, d[x]);
if (x < n) {
d[x+1] = abs(a[x+1] - a[x]);
gc.modify(1, 0, n+1, x+1, d[x+1]);
}
{
pii add = make_pair(a[x], x);
auto it = se.lower_bound(add);
if (it != se.begin() && (*prev(it)).ff == a[x]) {
last[x] = (*prev(it)).ss;
} else {
last[x] = 0;
}
prv.modify(1, 0, n+1, x, last[x]);
if (it != se.end()) {
if ((*it).ff == a[x]) {
last[(*it).ff] = x;
} else {
last[(*it).ff] = 0;
}
prv.modify(1, 0, n+1, (*it).ff, last[(*it).ff]);
}
se.insert(add);
}
} else {
int l, r; cin >> l >> r;
int small = mi.query(1, 0, n+1, l, r+1), big = ma.query(1, 0, n+1, l, r+1);
//debug("extreme", small, big);
if (small == big || r - l <= 1) {
cout << "YES\n";
} else {
int same = prv.query(1, 0, n+1, l, r+1);
int siz = r - l + 1;
//debug(same, siz);
//pary(last.begin(), last.end());
if (same >= l || (big - small) % (siz - 1) != 0) cout << "NO\n";
else {
int dis = (big - small) / (siz - 1);
int val = gc.query(1, 0, n+1, l+1, r+1);
//debug("dis", dis, val);
if (val % dis == 0) cout << "YES\n";
else cout << "NO\n";
}
}
}
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 7720kb
input:
5 7 1 1 1 10 1 2 1 3 2 1 5 1 5 4 1 3 7 2 2 4 2 2 5 2 4 5
output:
YES NO NO YES YES
result:
ok 5 lines
Test #2:
score: 0
Accepted
time: 1ms
memory: 7652kb
input:
2 1 0 1000000000 2 1 2
output:
YES
result:
ok single line: 'YES'
Test #3:
score: -100
Time Limit Exceeded
input:
81473 13549 972586683 972586964 972587245 972587526 972587807 972588088 972588369 972588650 972588931 972589212 972589493 972589774 972590055 972590336 972590617 972590898 972591179 972591460 972591741 972592022 972592303 972592584 972592865 972593146 972593427 972593708 972593989 972594270 97259455...