HDU6328 Rectangle Radar Scanner

S o u c e : 2018 Multi-University Training Contest 3
P r o b l e m : 二维平面上给出n=1e5个有权值w=1e9的点,且x坐标刚好从1到n各不相同,1<=y<=n。现在m=1e6的询问,每个询问给出一个矩形,问矩形内所有点的权值积、最大值、最小值。
I d e a : 查询离线,并按x轴进行分治。当前矩形刚好覆盖分治的中线时,由于这些矩形一边已经固定,所以用线段树扫两遍即可,这样查询就只有一个log。时间复杂度O((n log n + m) log n)。注意撤销的时候碰到未标记的部分就返回。

C o d e :

#include<bits/stdc++.h>
using namespace std;

#define lc o<<1
#define rc o<<1|1
#define fi first
#define se second
#define pb push_back
#define ALL(X) (X).begin(), (X).end()
#define bcnt(X) __builtin_popcountll(X)
#define CLR(A, X) memset(A, X, sizeof(A))
#pragma comment(linker, "/STACK:1024000000,1024000000")

using DB = double;
using LL = long long;
using PII = pair<int, int>;
const int INF = 0x3f3f3f3f;
const int N = 1e5+10, M = 1e6+10;
int MOD;

void input(int n, int &m);
inline int umin(const int &x, const int &y) { return x<y?x:y; }
inline int umax(const int &x, const int &y) { return x>y?x:y; }

int qid, ql, qr, qv;
int prod[M], mx[M], mn[M];
struct Node{ int l, r, mn, mx, s; } T[N<<2];
inline void pushup(int o) {
    T[o].s = 1LL*T[lc].s*T[rc].s%MOD;
    T[o].mn = min(T[lc].mn, T[rc].mn);
    T[o].mx = max(T[lc].mx, T[rc].mx);
}
void build(int o, int l, int r) {
    T[o].mn = INF, T[o].mx = -INF, T[o].s = 1;
    if((T[o].l=l) == (T[o].r=r)) return;
    int mid = l+r>>1;
    build(lc, l, mid); build(rc, mid+1, r);
}
void clean(int o = 1) {
    if(T[o].mn == INF) return;
    T[o].mn = INF, T[o].mx = -INF, T[o].s = 1;
    if(T[o].l == T[o].r) return;
    clean(lc); clean(rc);
}
void update(int o = 1) {
    if(T[o].l == T[o].r) {
        T[o].mn = umin(T[o].mn, qv);
        T[o].mx = umax(T[o].mx, qv);
        T[o].s = 1LL*T[o].s*qv%MOD;
        return;
    }
    int mid = T[o].l+T[o].r>>1;
    if(ql <= mid) update(lc); else update(rc);
    pushup(o);
}
void query(int o = 1) {
    if(T[o].mn == INF) return;
    if(ql<=T[o].l && qr>=T[o].r) {
        prod[qid] = 1LL*prod[qid]*T[o].s%MOD;
        mn[qid] = umin(mn[qid], T[o].mn);
        mx[qid] = umax(mx[qid], T[o].mx);
        return;
    }
    int mid = T[o].l+T[o].r>>1;
    if(ql <= mid) query(lc); if(qr > mid) query(rc);
}

struct RECT {
    int xl, xr, yl, yr, id;
    void print() {
        printf("id=%d xl=%d xr=%d yl=%d yr=%d\n", id, xl, xr, yl, yr);
    }
}rec[M], pool[M], b[M];
inline bool cmpl(const RECT &A, const RECT &B) { return A.xl > B.xl; }
inline bool cmpr(const RECT &A, const RECT &B) { return A.xr < B.xr; }

PII hou[N];
void solve(int nl, int nr, int ml, int mr) {
    if(nl>nr || ml>mr) return;
    int nm = nl+nr>>1, dl = ml-1, dr = mr+1, k = 0;
    for(int i = ml; i <= mr; i++) {
        if(rec[i].xr < nm) pool[++dl] = rec[i];
        else if(rec[i].xl > nm) pool[--dr] = rec[i];
        else b[k++] = rec[i];
    }

    sort(b, b+k, cmpl);
    int j = nm;
    for(int i = 0; i < k; i++) {
        while(j >= b[i].xl) {
            ql = hou[j].fi; qv = hou[j--].se;
            update();
        }
        ql = b[i].yl, qr = b[i].yr, qid = b[i].id;
        query();
    }
    clean();
    sort(b, b+k, cmpr);
    j = nm+1;
    for(int i = 0; i < k; i++) {
        while(j <= b[i].xr) {
            ql = hou[j].fi; qv = hou[j++].se;
            update();
        }
        ql = b[i].yl, qr = b[i].yr, qid = b[i].id;
        query();
    }
    clean();

    for(int i = ml; i <= dl; i++) rec[i] = pool[i];
    for(int i = dr; i <= mr; i++) rec[i] = pool[i];
    solve(nl, nm-1, ml, dl); solve(nm+1, nr, dr, mr);
}

int main() {
    int X;
    scanf("%d", &X);
    while(X--) {
        int n, m;
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            scanf("%d%d", &hou[i].fi, &hou[i].se);
        }
        input(n, m);
        build(1, 1, n);
        solve(1, n, 1, m);
        LL ans = 0;
        for(int i = 1; i <= m; i++) {
            if(mn[i] == INF) continue;
            ans += prod[i]^mx[i]^mn[i];
//            printf("ans = %d %d %d\n", prod[i], mx[i], mn[i]);
        }
        printf("%lld\n", ans);
    }
    return 0;
}

void input(int n, int &m) {
    int a[2], b[2], c[2], d[2], p, q, r, P;
    scanf("%d %d%d%d%d %d%d%d%d %d", &m, a,b,c,d, &p,&q,&r,&P, &MOD);
    auto get = [&](const int &x, const int &y)->int { return (1LL*p*x+1LL*q*y+r)%P; };
    for(int i = 1; i <= m; i++) {
        a[1] = get(a[0], b[0]); b[1] = get(b[0], a[0]);
        c[1] = get(c[0], d[0]); d[1] = get(d[0], c[0]);
        a[0] = a[1], b[0] = b[1], c[0] = c[1], d[0] = d[1];
        rec[i].xl = umin(a[0]%n, b[0]%n)+1;
        rec[i].xr = umax(a[0]%n, b[0]%n)+1;
        rec[i].yl = umin(c[0]%n, d[0]%n)+1;
        rec[i].yr = umax(c[0]%n, d[0]%n)+1;
        rec[i].id = i;
        prod[i] = 1, mn[i] = INF, mx[i] = -INF;
//        rec[i].print();
    }
}

猜你喜欢

转载自blog.csdn.net/qq_32506797/article/details/81391175