QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#268830#4940. Token DistancebruhWA 0ms49660kbC++2011.2kb2023-11-28 21:53:382023-11-28 21:53:39

Judging History

你现在查看的是最新测评结果

  • [2023-11-28 21:53:39]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:49660kb
  • [2023-11-28 21:53:38]
  • 提交

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'