QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#268830 | #4940. Token Distance | bruh | WA | 0ms | 49660kb | C++20 | 11.2kb | 2023-11-28 21:53:38 | 2023-11-28 21:53:39 |
Judging History
answer
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
typedef __int128 Int;
typedef vector<ll> vi;
typedef pair<ll, ll> ii;
typedef vector<ii> vii;
typedef pair<ll, ii> iii;
typedef unordered_map<ll, ll> unmap;
template<typename T> using pqmax = priority_queue<T>;
template<typename T> using pqmin = priority_queue<T, vector<T>, greater<T>>;
template<typename T> using oset = tree<T, null_type,less<T>, rb_tree_tag, tree_order_statistics_node_update>;
#define fi first
#define se second
#define sz size()
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define lg(n) (ll)__lg(n)
#define btpc __builtin_popcount
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define FOR(i,a,b) for(ll i = a; i <= b; i ++)
#define REP(i,a,b) for(ll i = a; i < b; i ++)
#define FORD(i,a,b) for(ll i = a; i >= b; i --)
#define FORS(i,a,b,c) for(ll i = a; i <= b; i += c)
#define FORDS(i,a,b,c) for(ll i = a; i >= b; i -= c)
#define FORA(x,a) for(auto x: a)
#define FORAA(l,r,a) for(auto [l, r]: a)
#define EL cerr << endl;
#define DEBUGN(a) cerr << a << endl;
#define DEBUGA(a, n) FOR (i, 1, n) cerr << a[i] << " "; cerr << endl;
#define DEBUG_AOP(a, n) FOR (i, 1, n) cerr << a[i].fi << " " << a[i].se << endl;
#define DEBUG_A2D(a, n, m) FOR (i, 1, n) {FOR (j, 1, m) cerr << a[i][j] << " "; cerr << endl;}
#define DEBUG cerr << "shut the fuck up please :3" << endl;
#define YES cout << "YES\n"; return;
#define NO cout << "NO\n"; return;
template<class X, class Y> bool mimi(X &x, const Y &y) {if(x>y){x=y;return 1;}return 0;}
template<class X, class Y> bool mama(X &x, const Y &y) {if(x<y){x=y;return 1;}return 0;}
istream &operator >> (istream &st, Int &a) {string s;a=0;st>>s;bool g=1;REP(i,0,s.sz){if(i==0&&s[i]=='-'){g = 0;continue;}a=a*10+s[i]-'0';}if(!g)a=-a;return st;}
ostream &operator << (ostream &st, const Int &a) {Int t=a;if(t==0){st<<0;return st;}if(t<0){st<<'-';t=-t;}string b;while(t!=0){b.pb((t%10+'0'));t/=10;}reverse(all(b));st<<b;return st;}
const ll nom = 2;
const ll base[] = {577, 677, 877, 977};
const ll mod[] = {(ll)1e9 + 2277, (ll)1e9 + 5277, (ll)1e9 + 8277, (ll)1e9 + 9277};
const ii dir[] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
const ll INF = 1e18;
const ll N = 1e5 + 5;
const ll T = 4*N - 3;
const ll M = 1e9 + 7;
const ll B = 50;
mt19937_64 rng(static_cast<ll>(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count()));
ll rand(ll l, ll r) {
return uniform_int_distribution<ll>(l, r)(rng);
}
struct STN {ll minVal, maxVal, sumVal;};
struct SegmentTree {
vector<STN> node;
const STN DEADNODE = {INF, -INF, 0};
ll uu, vv;
SegmentTree(ll n, ll uu, ll vv): node(4 * n + 10), uu(uu), vv(vv) {
fill(all(node), DEADNODE);
};
STN merge(STN a, STN b) {return {min(a.minVal, b.minVal), max(a.maxVal, b.maxVal), a.sumVal + b.sumVal};}
void update(ll pos, ll val) {update(pos, val, 1, uu, vv);}
void update(ll pos, ll val, ll id, ll l, ll r) {
if (l > pos || r < pos) return;
if (l == r) {
node[id].minVal = val;
node[id].maxVal = val;
node[id].sumVal = val;
return;
}
ll mid = (l + r) >> 1;
update(pos, val, id << 1, l, mid);
update(pos, val, id << 1 | 1, mid + 1, r);
node[id] = merge(node[id << 1], node[id << 1 | 1]);
}
STN get(ll u, ll v) {return get(u, v, 1, uu, vv);}
STN get(ll u, ll v, ll id, ll l, ll r) {
if (l > v || r < u) return DEADNODE;
if (u <= l && r <= v) return node[id];
ll mid = (l + r) >> 1;
return merge(get(u, v, id << 1, l, mid), get(u, v, id << 1 | 1, mid + 1, r));
}
};
struct STNS {ll val, cnt;};
struct SegmentTreeSum {
vector<STNS> node;
const STNS DEADNODE = {(ll)0, 0};
ll uu, vv;
void init(ll n, ll uu, ll vv) {
node.resize(4 * n + 10);
this->uu = uu;
this->vv = vv;
fill(all(node), DEADNODE);
}
STNS merge(STNS a, STNS b) {return {a.val + b.val, a.cnt + b.cnt};}
void update(ll pos, ll val, ll cnt) {update(pos, val, cnt, 1, uu, vv);}
void update(ll pos, ll val, ll cnt, ll id, ll l, ll r) {
if (l > pos || r < pos) return;
if (l == r) {
node[id].val = val;
node[id].cnt = cnt;
return;
}
ll mid = (l + r) >> 1;
update(pos, val, cnt, id << 1, l, mid);
update(pos, val, cnt, id << 1 | 1, mid + 1, r);
node[id] = merge(node[id << 1], node[id << 1 | 1]);
}
STNS get(ll u, ll v) {return get(u, v, 1, uu, vv);}
STNS get(ll u, ll v, ll id, ll l, ll r) {
if (l > v || r < u) return DEADNODE;
if (u <= l && r <= v) return node[id];
ll mid = (l + r) >> 1;
return merge(get(u, v, id << 1, l, mid), get(u, v, id << 1 | 1, mid + 1, r));
}
};
struct MSTN {
oset<ii> a;
multiset<ll> b;
set<ll> c;
ll cntMultiset, cntSet;
};
struct MergeSortTree {
vector<MSTN> node;
const MSTN DEADNODE = {oset<ii>(), multiset<ll>(), set<ll>(), 0, 0};
ll uu, vv;
void init(ll n, ll uu, ll vv) {
node.resize(n * 4, DEADNODE);
this->uu = uu;
this->vv = vv;
}
void build(ll n, ll *a) {build(n, a, 1, uu, vv);}
void build(ll n, ll *a, ll id, ll l, ll r) {
if (l == r) {
node[id].a.insert({a[r], r});
node[id].b.insert(a[r]);
node[id].c.insert(a[r]);
return;
}
ll mid = (l + r) >> 1;
build(n, a, id << 1, l, mid);
build(n, a, id << 1 | 1, mid + 1, r);
FORA (x, node[id << 1].a) node[id].a.insert(x);
FORA (x, node[id << 1 | 1].a) node[id].a.insert(x);
FORA (x, node[id << 1].b) node[id].b.insert(x);
FORA (x, node[id << 1 | 1].b) node[id].b.insert(x);
FORA (x, node[id << 1].c) node[id].c.insert(x);
FORA (x, node[id << 1 | 1].c) node[id].c.insert(x);
}
void update(ll pos, ii oldValue, ii newValue) {update(pos, oldValue, newValue, 1, uu, vv);}
void update(ll pos, ii oldValue, ii newValue, ll id, ll l, ll r) {
if (pos < l || pos > r) return;
if (l == r) {
node[id].cntMultiset = 1;
node[id].cntSet = 1;
if (oldValue != newValue) {
node[id].a.erase(oldValue);
node[id].a.insert(newValue);
}
if (oldValue.fi != newValue.fi) {
if (node[id].b.find(newValue.fi) == node[id].b.end()) node[id].b.insert(newValue.fi);
node[id].b.erase(oldValue.fi);
node[id].b.insert(newValue.se);
if (node[id].b.find(oldValue.fi) == node[id].b.end()) node[id].c.erase(oldValue.fi);
}
return;
}
ll mid = (l + r) >> 1;
update(pos, oldValue, newValue, id >> 1, l, mid);
update(pos, oldValue, newValue, id >> 1 | 1, mid + 1, r);
if (oldValue != newValue) {
node[id].a.erase(oldValue);
node[id].a.insert(newValue);
}
if (oldValue.fi != newValue.fi) {
if (node[id].b.find(newValue.fi) == node[id].b.end()) node[id].b.insert(newValue.fi);
node[id].b.erase(oldValue.fi);
node[id].b.insert(newValue.se);
if (node[id].b.find(oldValue.fi) == node[id].b.end()) node[id].c.erase(oldValue.fi);
}
node[id].cntMultiset = node[id].b.size();
node[id].cntSet = node[id].c.size();
}
ll get(ll u, ll v, ll x) {return get(u, v, x, 1ll, uu, vv);}
ll get(ll u, ll v, ll x, ll id, ll l, ll r) {
if (r < u || l > v) return 0;
if (v >= r && l >= u) return node[id].a.order_of_key({x + 1, 0});
ll mid = (l + r) >> 1;
return get(u, v, x, id << 1, l, mid) + get(u, v, x, id << 1 | 1, mid + 1, r);
}
ll getCntMultiset(ll u, ll v) {return getCntMultiset(u, v, 1ll, uu, vv);}
ll getCntMultiset(ll u, ll v, ll id, ll l, ll r) {
if (r < u || l > v) return 0;
if (v >= r && l >= u) return node[id].b.size();
ll mid = (l + r) >> 1;
return getCntMultiset(u, v, id << 1, l, mid) + getCntMultiset(u, v, id << 1 | 1, mid + 1, r);
}
ll getCntSet(ll u, ll v) {return getCntSet(u, v, 1ll, uu, vv);}
ll getCntSet(ll u, ll v, ll id, ll l, ll r) {
if (r < u || l > v) return 0;
if (v >= r && l >= u) return node[id].c.size();
ll mid = (l + r) >> 1;
return getCntSet(u, v, id << 1, l, mid) + getCntSet(u, v, id << 1 | 1, mid + 1, r);
}
};
ll n, q;
ll a[N];
ll b[B + 1][N];
SegmentTree st(N, 0, N - 1);
SegmentTreeSum rt[B + 1];
MergeSortTree mst;
void solve(ll testID) {
cin >> n >> q;
FOR (i, 1, n) {
cin >> a[i];
st.update(i, a[i]);
}
mst.init(n, 1, n);
mst.build(n, a);
// mst.update(5, {1, 5}, {4, 5});
// mst.update(3, {1, 3}, {7, 3});
// EL EL
// FORAA (l, r, mst.node[1].a) cout << l << " " << r << endl;
// EL EL
FOR (i, 1, B) {
rt[i].init(n, 1, n);
FOR (j, 1, n) {
b[i][j] = a[j] * rand(0, 1);
rt[i].update(j, b[i][j], (b[i][j] != 0));
}
}
FOR (_, 1, q) {
ll type, l, r;
cin >> type >> l >> r;
if (type == 1) {
st.update(l, r);
FOR (i, 1, B) {
if (rt[i].get(l, l).cnt == 0) continue;
rt[i].update(l, r, 1);
}
mst.update(l, {a[l], l}, {r, l});
a[l] = r;
}
if (type == 2) {
STN node = st.get(l, r);
ll maxVal = node.maxVal;
ll minVal = node.minVal;
ll sumVal = node.sumVal;
if (maxVal == minVal) {cout << "YES\n"; continue;}
ll mod = (maxVal - minVal) / (r - l);
if ((maxVal - minVal) % (r - l) != 0) {cout << "NO\n"; continue;}
if (sumVal != (r - l + 1) * (minVal + maxVal) / 2) {cout << "NO\n"; continue;}
if (mst.getCntMultiset(l, r) == mst.getCntSet(l, r)) {cout << "NO\n"; continue;}
bool res = true;
FOR (i, 1, B) {
ll sum = rt[i].get(l, r).val;
ll cnt = rt[i].get(l, r).cnt;
ll pos = rand(l, r);
if ((sum % mod != cnt * a[pos] % mod) || (mst.get(l, r, minVal + (pos - l) * mod) < pos - l + 1)) {
res = false;
break;
}
}
if (res) cout << "YES\n";
else cout << "NO\n";
}
}
}
signed main() {
// freopen("a.INP", "r", stdin);
// freopen("a.OUT", "w", stdout);
ios_base::sync_with_stdio(0); cin.tie(0);
int test = 1;
// cin >> test;
FOR (i, 1, test) solve(i);
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Wrong Answer
time: 0ms
memory: 49660kb
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 NO NO
result:
wrong answer 4th lines differ - expected: 'YES', found: 'NO'