HDU 5737 Differencia set + Chairman of the tree

HDU 5737

Obviously we can find data is random.

We set to maintain the same value segment, because it is set inside a random segment size is reduced too quickly, probably an average of about 30.

Violence each query processing for each segment to find the same accumulated answers Chairman tree on it.

However, this seems not a scalar calculation, computational complexity scale (n + m) * log (n) and the data may not random.

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define LL long long
#define LD long double
#define ull unsigned long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ALL(x) (x).begin(), (x).end()
#define fio ios::sync_with_stdio(false); cin.tie(0);

using namespace std;

const int N = 1e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = (int)1e9 + 7;
const double eps = 1e-8;
const double PI = acos(-1);

template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;}
template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < 0) a += mod;}
template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;}
template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;}

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int n, m, A[N], B[N];

struct Line {
    int l, r, val;
    bool operator < (const Line &rhs) const {
        return r < rhs.r;
    }
};

set<Line> S;

int change(int L, int R, int val) {
    while(1) {
        auto it = S.lower_bound(Line{0, L, 0});
        if(it == S.end() || it->l > R) break;
        Line tmp = *it;
        S.erase(it);
        if(tmp.l < L) {
            S.insert(Line{tmp.l, L - 1, tmp.val});
        }
        if(tmp.r > R) {
            S.insert(Line{R + 1, tmp.r, tmp.val});
        }
    }
    S.insert(Line{L, R, val});
}


int Rt[N], hs[N], hs_cnt;
struct ChairManTree {
    int tree_cnt;
    struct Node {
        int sum, ls, rs;
    } a[N * 20];
    void update(int p, int l, int r, int &x, int y) {
        x = ++tree_cnt;
        a[x] = a[y];
        a[x].sum++;
        if(l == r) return;
        int mid = l + r >> 1;
        if(p <= mid) update(p, l, mid, a[x].ls, a[y].ls);
        else update(p, mid + 1, r, a[x].rs, a[y].rs);
    }
    int query(int val, int l, int r, int x, int y) {
        if(hs[r] <= val) return a[x].sum - a[y].sum;
        if(hs[l] > val) return 0;
        int mid = l + r >> 1;
        return query(val, l, mid, a[x].ls, a[y].ls) + query(val, mid + 1, r, a[x].rs, a[y].rs);
    }
} CT;

int query(int L, int R) {
    int ql, qr, ans = 0;
    auto it = S.lower_bound(Line{0, L, 0});
    while(it != S.end() && it->l <= R) {
        ql = max(it->l, L);
        qr = min(it->r, R);
        ans += CT.query(it->val, 1, hs_cnt, Rt[qr], Rt[ql - 1]);
        ++it;
    }
    return ans;
}

int a, b, C = ~(1 << 31), M = (1 << 16) - 1;

int rnd(int last) {
    a = (36969 + (last >> 3)) * (a & M) + (a >> 16);
    b = (18000 + (last >> 3)) * (b & M) + (b >> 16);
    return (C & ((a << 16) + b)) % 1000000000;
}

void init() {
    S.clear();
    CT.tree_cnt = 0;
    hs_cnt = 0;
}

int main() {
    int T; scanf("%d", &T);
    while(T--) {
        scanf("%d%d%d%d", &n, &m, &a, &b);
        init();
        for(int i = 1; i <= n; i++) {
            scanf("%d", &A[i]);
            S.insert(Line{i, i, A[i]});
        }
        for(int i = 1; i <= n; i++) {
            scanf("%d", &B[i]);
            hs[++hs_cnt] = B[i];
        }
        sort(hs + 1, hs + 1 + hs_cnt);
        hs_cnt = unique(hs + 1, hs + 1 + hs_cnt) - hs - 1;
        for(int i = 1; i <= n; i++) {
            B[i] = lower_bound(hs + 1, hs + 1 + hs_cnt, B[i]) - hs;
            CT.update(B[i], 1, hs_cnt, Rt[i], Rt[i - 1]);
        }
        int ans = 0;
        int last = 0, l, r, x;
        for(int i = 1; i <= m; i++) {
            l = rnd(last) % n + 1;
            r = rnd(last) % n + 1;
            if(l > r) swap(l, r);
            x = rnd(last) + 1;
            if((l + r + x) & 1) {
                change(l, r, x);
            }
            else {
                last = query(l, r);
                add(ans, 1LL * i * last % mod);
            }
        }
        printf("%d\n", years); 
    } 
    Return  0 ; 
} 

/ * 
* /

 

Guess you like

Origin www.cnblogs.com/CJLHY/p/11517511.html