个人ACM模板(持续更新)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_35850147/article/details/102690827
// 快读
inline const int read()
{
    int x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
    return x * f;
}

// 快速幂
ll qpow(ll x, ll k)
{
    ll res = 1;
    while (k)
    {
        if (k & 1) res = res * x % mod;
        x = x * x % mod; k >>= 1;
    }
    return res;
}

// 矩阵快速幂
// POJ3070 求斐波那契数列第n项取模
#include <iostream>
#include <cstring>
using namespace std;
 
const int mod = 10000;
const int v[4] = {0, 1, 1, 2};
struct matrix
{
    int mat[3][3];
    void init()
    {
        memset(mat, 0, sizeof(mat));
        for (int i = 0; i < 3; i++) mat[i][i] = 1;
    }
};

matrix mul(const matrix& a, const matrix& b)
{
    matrix res;
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            res.mat[i][j] = 0;
            for (int k = 0; k < 3; k++) res.mat[i][j] = (res.mat[i][j] + a.mat[i][k] * b.mat[k][j]) % mod;
        }
    }
    return res;
}
 
matrix quick_pow(matrix a, int n)
{
    matrix res; res.init();
    while (n)
    {
        if (n & 1) res = mul(res, a);
        a = mul(a, a); n >>= 1;
    }
    return res;
}
 
int main()
{
    matrix base;
    memset(base.mat, 0, sizeof(base.mat));
    base.mat[0][0] = base.mat[0][1] = base.mat[1][0] = base.mat[2][1] = 1;
    int n;
    while (cin >> n && n != -1)
    {
        if (n <= 3) cout << v[n] << endl;
        else
        {
            matrix pow = quick_pow(base, n - 3);
            int res = 0;
            for (int i = 0; i < 3; i++) res = (res + pow.mat[0][i] * v[3 - i]) % mod;
            cout << res << endl;
        }
    }
    return 0;
}

// 威尔逊定理
// (p − 1)! == −1 (mod p)
// 若p为质数,则p可整除(p - 1)! + 1

// 费马小定理
// a ^ (p - 1) == 1 (mod p)

// 欧拉定理
// a ^ φ(m) == 1 (mod m) (gcd(a, m) == 1, m >= 2)

// 欧拉函数
// φ(n): 小于或等于n的正整数中与n互质的数目
// 1, 1, 2, 2, 4, 2, 6, 4, 6, 4, 10, 4, 12, 6

// 欧拉函数 打表
void get_euler()
{
    for (int i = 1; i < maxn; i++)
        phi[i] = i;
    for (int i = 2; i < maxn; i++)
        if (phi[i] == i)
            for (int j = i; j < maxn; j += i)
                phi[j] = phi[j] / i * (i - 1);
}

// 欧拉函数 求值
ll euler(int n)
{
    ll res = 1;
    for (int i = 2; i <= sqrt(n); i++)
    {
        if (n % i == 0)
        {
            n /= i; res *= i - 1;
            while (n % i == 0) { n /= i; res *= i; }
        }
    }
    if (n > 1) res *= n - 1;
    return res;
}

// 乘法逆元
// n在模p意义下的乘法逆元
// (1 / n) % p == n ^ (p - 2) % p

// 线性求乘法逆元
// inv[i] = (ll)(p - p / i) * inv[p % i] % p;

// Polya定理
// m颗珠子,n种颜色: L = (1 / m) * Σ(i = 1, m)(n ^ gcd(i, m))
// 当n == m: L = (1 / n) * Σ(p | n)(φ(p) * n ^ (n / p)) = Σ(p | n)(φ(p) * n ^ (n / p - 1))

// 链式前向星
int head[maxn];
struct edge { int v, w, next; } e[maxm];
void addEdge(int u, int v, int w)
{
    e[cnt].v = v;
    e[cnt].w = w;
    e[cnt].next = head[u];
    head[u] = cnt++;
}

// 最短路径 Dijkstra
struct node
{
    int u, w;
    bool operator < (const node& n) const { return w > n.w; }
};
priority_queue<node> q;

void dijkstra(int src)
{
    memset(vis, false, sizeof(vis));
    for (int i = 1; i <= n; i++) dis[i] = inf;
    dis[src] = 0;
    q.push(node{src, 0});
    while (!q.empty())
    {
        int u = q.top().u; q.pop();
        if (vis[u]) continue;
        vis[u] = true;
        for (int i = head[u]; ~i; i = e[i].next)
        {
            int v = e[i].v, w = e[i].w;
            if (dis[v] > dis[u] + w)
            {
                dis[v] = dis[u] + w;
                q.push(node{v, dis[v]});
            }
        }
    }
}

// 最短路径 SPFA
void spfa(int src)
{
    memset(vis, false, sizeof(vis));
    for (int i = 1; i <= n; i++) dis[i] = inf;
    dis[s] = 0;
    queue<int> q;
    q.push(s);
    while (!q.empty())
    {
        int u = q.front(); q.pop();
        vis[u] = false;
        for (int i = head[u]; ~i; i = e[i].next)
        {
            int v = e[i].v, w = e[i].w;
            if (dis[v] > dis[u] + w)
            {
                dis[v] = dis[u] + w;
                if (!vis[v])
                {
                    q.push(v);
                    vis[v] = true;
                }
            }
        }
    }
}

// 无向图找环 DFS
void dfs(int cur, int pre, int dep)
{
    vis[cur] = 1; depth[cur] = dep;
    for (int i = head[cur]; ~i; i = e[i].next)
    {
        int nxt = e[i].to;
        if (nxt == pre) continue;
        if (vis[nxt] == 0) dfs(nxt, cur, dep + 1);
        else if (vis[nxt] == 1) loop[lpcnt++] = depth[cur] - depth[nxt] + 1;
    }
    vis[cur] = 2;
}

// 最近公共祖先(LCA) Tarjan离线
struct edge { int next, to; } e[maxm];
struct que { int next, to, id; } q[maxq];

void tarjan(int u)
{
    vis[u] = true;
    for (int i = ehead[u]; i != -1; i = e[i].next)
    {
        int v = e[i].to;
        if (!vis[v])
        {
            tarjan(v);
            Union(u, v);
        }
    }
    for (int i = qhead[u]; i != -1; i = q[i].next)
    {
        int v = q[i].to;
        if (vis[v]) ans[q[i].id] = Find(v);
    }
}

// 强连通分量 Tarjan
// dfn[] 当前点的DFS遍历时间戳
// low[] 当前点及其所有子孙节点所能连接的点的最小dfn
// sta[] 当前所有可能构成强连通分量的点
// vis[] 当前点是否在sta[]中
void tarjan(int u)
{
    vis[u] = true;
    dfn[u] = low[u] = ++dep;
    sta[top++] = u;
    for (int i = head[u]; ~i; i = e[i].next)
    {
        int v = e[i].to;
        if (!dfn[v])
        {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if (vis[v]) low[u] = min(low[u], dfn[v]);
    }
    if (dfn[u] == low[u])
    {
        color[u] = ++cnt; 
        vis[u] = false;
        while (sta[--top] != u)
        {
            vis[sta[top]] = false;
            color[sta[top]] = cnt;
        }
    }
}

// 割点 Tarjan
void tarjan(int cur, int pre)
{
    int child = 0;
    low[cur] = dfn[cur] = ++dep;
    for (int i = head[cur]; ~i; i = e[i].next)
    {
        int nxt = e[i].to;
        if (!dfn[nxt])
        {
            child++;
            tarjan(nxt, cur);
            low[cur] = min(low[cur], low[nxt]);
            if (pre != cur && low[nxt] >= dfn[cur] && !iscut[cur])
            {
                ccnt++;
                iscut[cur] = true;
            }
        }
        else if (nxt != pre) low[cur] = min(low[cur], dfn[nxt]);
    }
    if (pre == cur && child >= 2)
    {
        ccnt++;
        iscut[cur] = true;
    }
}

// 二分图最大匹配 / 最小顶点覆盖 / 最小边覆盖 / 最大独立集 Hungary
// 最小顶点覆盖 = 二分图最大匹配 最小的顶点集合使二分图的每条边至少与其中一个点关联
// 最小边覆盖 = |V| - 二分图最大匹配 最小的边集合,覆盖二分图中所有顶点
// 最大独立集 = |V| - 二分图最大匹配 最大的顶点集合,其中任意两点在二分图中无对应边
// 洛谷P3386 【模板】二分图匹配
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn = 1e3 + 10;
int n, m, e, match[maxn];
bool vis[maxn], g[maxn][maxn];

inline const int read()
{
    int x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
    return x * f;
}

bool dfs(int u)
{
    for (int v = 1; v <= m; v++)
    {
        if (!vis[v] && g[u][v])
        {
            vis[v] = true;
            if (!match[v] || dfs(match[v]))
            {
                match[v] = u;
                return true;
            }
        }
    }
    return false;
}

int main()
{
    n = read(); m = read(); e = read();
    while (e--)
    {
        int a = read(), b = read();
        if (a <= n && b <= m) g[a][b] = true;
    }
    int ans = 0;
    for (int i = 1; i <= n; i++)
    {
        memset(vis, false, sizeof(vis));
        ans += dfs(i);
    }
    printf("%d\n", ans);
    return 0;
}

// K短路 A*
// POJ2449 Remmarguts' Date
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
 
const int maxn = 1e3 + 10, maxm = 1e5 + 10, inf = 1e9;
bool vis[maxn];
int n, m, s, t, k, tot;
int head1[maxn], head2[maxn], dis[maxn];
struct enode
{
    int v, w, next;
} e1[maxm], e2[maxm];
struct anode
{
    int id, f, g;
    bool operator < (const anode &a) const
    {
        return f != a.f ? f > a.f : g > a.g;
    }
};
 
inline const int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
    return x * f;
}
 
void addedge(int u, int v, int w)
{
    ++tot;
    e1[tot].v = v; e1[tot].w = w; e1[tot].next = head1[u]; head1[u] = tot;
    e2[tot].v = u; e2[tot].w = w; e2[tot].next = head2[v]; head2[v] = tot;
}
 
void spfa(int s)
{
    for (int i = 1; i <= n; i++)
        dis[i] = inf;
    dis[s] = 0;
    queue<int> q;
    q.push(s);
    while (!q.empty())
    {
        int u = q.front();
        q.pop();
        vis[u] = false;
        for (int i = head2[u]; i; i = e2[i].next)
        {
            int v = e2[i].v, w = e2[i].w;
            if (dis[v] > dis[u] + w)
            {
                dis[v] = dis[u] + w;
                if (!vis[v])
                {
                    vis[v] = true;
                    q.push(v);
                }
            }
        }
    }
}
 
void a_star(int s, int t)
{
    if (s == t) k++;
    priority_queue<anode> q;
    q.push(anode{s, 0, 0});
    int cnt = 0;
    while (!q.empty())
    {
        anode a = q.top();
        q.pop();
        if (a.id == t && ++cnt == k)
        {
            printf("%d\n", a.f);
            return;
        }
        for (int i = head1[a.id]; i; i = e1[i].next)
            q.push(anode{e1[i].v, a.g + e1[i].w + dis[e1[i].v], a.g + e1[i].w});
    }
    printf("-1\n");
}
 
int main()
{
    n = read(); m = read();
    for (int i = 1, u, v, w; i <= m; i++)
    {
        u = read(); v = read(); w = read();
        addedge(u, v, w);
    }
    s = read(); t = read(); k = read();
    spfa(t);
    a_star(s, t);
    return 0;
}

// 树状数组
int lowbit(int x)
{
    return x & -x;
}
 
void add(int p, int x)
{ 
    for (int i = p; i <= n; i += lowbit(i)) 
        tree[i] += x;
}
 
int getSum(int p)
{
    int res = 0;
    for (int i = p; i > 0; i -= lowbit(i))
        res += tree[i];
    return res;
}

// 线段树
struct node { int l, r; ll sum, lazy; } tree[maxn << 2];

inline int ls(int id) { return id << 1; }
inline int rs(int id) { return id << 1 | 1; }

void push_up(int id) { tree[id].sum = tree[ls(id)].sum + tree[rs(id)].sum; }

void push_down(int id)
{
    if (tree[id].lazy)
    {
        tree[ls(id)].sum += (tree[ls(id)].r - tree[ls(id)].l + 1) * tree[id].lazy;
        tree[rs(id)].sum += (tree[rs(id)].r - tree[rs(id)].l + 1) * tree[id].lazy;
        tree[ls(id)].lazy += tree[id].lazy;
        tree[rs(id)].lazy += tree[id].lazy;
        tree[id].lazy = 0;
    }
}

void build(int id, int l, int r)
{
    if ((tree[id].l = l) == (tree[id].r = r))
    {
        scanf("%lld", &tree[id].sum);
        return;
    }
    int mid = (l + r) >> 1;
    build(ls(id), l, mid);
    build(rs(id), mid + 1, r);
    push_up(id);
}

void update(int id, int l, int r, ll v)
{
    if (tree[id].l == l && tree[id].r == r)
    {
        tree[id].sum += (r - l + 1) * v;
        tree[id].lazy += v;
        return;
    }
    push_down(id);
    int mid = (tree[id].l + tree[id].r) >> 1;
    if (r <= mid) update(ls(id), l, r, v);
    else if (l > mid) update(rs(id), l, r, v);
    else
    {
        update(ls(id), l, mid, v);
        update(rs(id), mid + 1, r, v);
    }
    push_up(id);
}

ll query(int id, int l, int r)
{
    if (tree[id].l == l && tree[id].r == r) return tree[id].sum;
    push_down(id);
    int mid = (tree[id].l + tree[id].r) >> 1;
    if (r <= mid) return query(ls(id), l, r);
    if (l > mid) return query(rs(id), l, r);
    return query(ls(id), l, mid) + query(rs(id), mid + 1, r);
}

 // 线段树区间合并
// POJ3667 Hotel
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

const int maxn = 5e4 + 10;
struct node { int l, r, sum, lsum, rsum, lz; } tree[maxn << 2];
// sum: 该节点区间内状态全部为0的最大子区间长度

inline const int read()
{
    int x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
    return x * f;
}

inline int ls(int id) { return id << 1; }
inline int rs(int id) { return id << 1 | 1; }

void build(int id, int l, int r)
{
    tree[id].lz = -1;
    tree[id].l = l;
    tree[id].r = r;
    tree[id].sum = tree[id].lsum = tree[id].rsum = r - l + 1;
    if (l == r) return;
    int mid = (l + r) >> 1;
    build(ls(id), l, mid);
    build(rs(id), mid + 1, r);
}

void push_up(int id)
{
    tree[id].lsum = tree[ls(id)].lsum;
    tree[id].rsum = tree[rs(id)].rsum;
    if (tree[ls(id)].sum == tree[ls(id)].r - tree[ls(id)].l + 1) tree[id].lsum += tree[rs(id)].lsum;
    if (tree[rs(id)].sum == tree[rs(id)].r - tree[rs(id)].l + 1) tree[id].rsum += tree[ls(id)].rsum;
    tree[id].sum = max(max(tree[ls(id)].sum, tree[rs(id)].sum), tree[ls(id)].rsum + tree[rs(id)].lsum);
}

void push_down(int id)
{
    if (tree[id].lz != -1)
    {
        tree[ls(id)].lz = tree[rs(id)].lz = tree[id].lz;
        tree[ls(id)].sum = tree[ls(id)].lsum = tree[ls(id)].rsum = tree[id].lz ? 0 : tree[ls(id)].r - tree[ls(id)].l + 1;
        tree[rs(id)].sum = tree[rs(id)].lsum = tree[rs(id)].rsum = tree[id].lz ? 0 : tree[rs(id)].r - tree[rs(id)].l + 1;
        tree[id].lz = -1;
    }
}

void update(int id, int l, int r, bool x)
{
    if (tree[id].l == l && tree[id].r == r)
    {
        tree[id].lz = x;
        tree[id].sum = tree[id].lsum = tree[id].rsum = x ? 0 : tree[id].r - tree[id].l + 1;
        return;
    }
    push_down(id);
    int mid = (tree[id].l + tree[id].r) >> 1;
    if (r <= mid) update(ls(id), l, r, x);
    else if (l > mid) update(rs(id), l, r, x);
    else
    {
        update(ls(id), l, mid, x);
        update(rs(id), mid + 1, r, x);
    }
    push_up(id);
}

// 查询l, r区间内第一个状态全部为0且长度达到x的子区间左边界
int query(int id, int l, int r, int x)
{
    if (l == r) return l;
    push_down(id);
    int mid = (tree[id].l + tree[id].r) >> 1;
    if (tree[ls(id)].sum >= x) return query(ls(id), l, mid, x);
    if (tree[ls(id)].rsum + tree[rs(id)].lsum >= x) return mid - tree[ls(id)].rsum + 1;
    return query(rs(id), mid + 1, r, x);
}

int main()
{
    int n = read(), m = read();
    build(1, 1, n);
    while (m--)
    {
        int ope = read(), k, a, b;
        switch (ope)
        {
            case 1:
                k = read();
                if (tree[1].sum < k) printf("0\n");
                else
                {
                    printf("%d\n", a = query(1, 1, n, k));
                    update(1, a, a + k - 1, true);
                }
                break;
            case 2:
                a = read(); b = read();
                update(1, a, a + b - 1, false);
        }
    }
    return 0;
}

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

const int maxn = 5e4 + 10;
struct node { int l, r, sum, lsum, rsum; } tree[maxn << 2];
// sum: 当前节点区间内最大连通子区间长度

inline const int read()
{
    int x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
    return x * f;
}

inline int ls(int id) { return id << 1; }
inline int rs(int id) { return id << 1 | 1; }

void build(int id, int l, int r)
{
    tree[id].l = l;
    tree[id].r = r;
    tree[id].lsum = tree[id].rsum = tree[id].sum = r - l + 1;
    if (l == r) return;
    int mid = (l + r) >> 1;
    build(ls(id), l, mid);
    build(rs(id), mid + 1, r);
}

void push_up(int id)
{
    tree[id].lsum = tree[ls(id)].lsum;
    tree[id].rsum = tree[rs(id)].rsum;
    if ((tree[ls(id)].sum) == tree[ls(id)].r - tree[ls(id)].l + 1) tree[id].lsum += tree[rs(id)].lsum;
    if ((tree[rs(id)].sum) == tree[rs(id)].r - tree[rs(id)].l + 1) tree[id].rsum += tree[ls(id)].rsum;
    tree[id].sum = max(max(tree[ls(id)].sum, tree[rs(id)].sum), tree[ls(id)].rsum + tree[rs(id)].lsum);
}

void update(int id, int tar, bool x)
{
    if (tree[id].l == tar && tree[id].r == tar)
    {
        tree[id].lsum = tree[id].rsum = tree[id].sum = x;
        return;
    }
    int mid = (tree[id].l + tree[id].r) >> 1;
    if (tar <= mid) update(ls(id), tar, x);
    else update(rs(id), tar, x);
    push_up(id);
}

// 查询在当前节点区间内包含目标节点的最大连通子区间长度
int query(int id, int tar)
{
    if (tree[id].l == tree[id].r || tree[id].sum == tree[id].r - tree[id].l + 1 || tree[id].sum == 0) return tree[id].sum;
    int mid = (tree[id].l + tree[id].r) >> 1;
    if (tar <= mid) return tar >= tree[ls(id)].r - tree[ls(id)].rsum + 1 ? query(ls(id), tar) + query(rs(id), mid + 1) : query(ls(id), tar);
    return tar <= tree[rs(id)].l + tree[rs(id)].lsum - 1 ? query(rs(id), tar) + query(ls(id), mid) : query(rs(id), tar);
}

int main()
{
    int n, m, cnt, des[maxn];
    while (~scanf("%d%d", &n, &m))
    {
        cnt = 0;
        build(1, 1, n);
        while (m--)
        {
            char ope[2]; int x;
            scanf("%s", ope);
            switch (ope[0])
            {
                case 'D':
                    scanf("%d", &x);
                    des[cnt++] = x;
                    update(1, x, 0);
                    break;
                case 'Q':
                    scanf("%d", &x);
                    printf("%d\n", query(1, x));
                    break;
                case 'R':
                    update(1, des[--cnt], 1);
            }
        }
    }
    return 0;
}

// 扫描线
// The Preliminary Contest for ICPC Asia Nanjing 2019 A. The beautiful values of the palace
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn = 1e6 + 10;
const int maxm = 1e5 + 10;
int t, n, m, p, cnt, ans[maxm];
struct node { int l, r, sum; } tree[maxn << 2];
struct cor { int x, y, type, qid; } cord[maxm << 2];
struct qes { int x1, x2; } qest[maxm];
// type == 0: square for update, type == 1: lower left square for query, type == 2: upper right square for query

inline const int read()
{
    int x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
    return x * f;
}

int getVal(ll x, ll y)
{
    x = x - n / 2 - 1;
    y = y - n / 2 - 1;
    ll tmp = max(abs(x), abs(y));
    ll num = x >= y ? (ll)n * n - tmp * tmp * 4 - tmp * 2 - x - y : (ll)n * n - tmp * tmp * 4 + tmp * 2 + x + y;
    int res = 0;
    do { res += num % 10; num /= 10; } while (num);
    return res;
}

bool cmp(const cor& a, const cor& b)
{
    if (a.y != b.y) return a.y < b.y;
    if (a.x != b.x) return a.x < b.x;
    if ((a.type == 0 && b.type == 1) || (a.type == 1 && b.type == 0)) return a.type > b.type;
    return a.type < b.type;
}

inline int ls(int id) {return id << 1;}
inline int rs(int id) {return id << 1 | 1;}

void push_up(int id)
{
    tree[id].sum = tree[ls(id)].sum + tree[rs(id)].sum;
}

void build(int id, int l, int r)
{
    tree[id].l = l; tree[id].r = r; tree[id].sum = 0;
    if (l == r) return;
    int mid = (l + r) >> 1;
    build(ls(id), l, mid);
    build(rs(id), mid + 1, r);
    push_up(id);
}

void update(int id, int l, int r, int v)
{
    if (tree[id].l == l && tree[id].r == r)
    {
        tree[id].sum += (r - l + 1) * v;
        return;
    }
    int mid = (tree[id].l + tree[id].r) >> 1;
    if (r <= mid) update(ls(id), l, r, v);
    else if (l > mid) update(rs(id), l, r, v);
    else
    {
        update(ls(id), l, mid, v);
        update(rs(id), mid + 1, r, v);
    }
    push_up(id);
}

int query(int id, int l, int r)
{
    if (tree[id].l == l && tree[id].r == r) return tree[id].sum;
    int mid = (tree[id].l + tree[id].r) >> 1;
    if (r <= mid) return query(ls(id), l, r);
    if (l > mid) return query(rs(id), l, r);
    return query(ls(id), l, mid) + query(rs(id), mid + 1, r);
}

int main()
{
    t = read();
    while (t--)
    {
        cnt = 0;
        n = read(); m = read(); p = read();
        build(1, 1, n);
        for (int i = 0; i < m; i++)
        {
            int x = read(), y = read();
            cord[cnt++] = cor{x, y, 0, 0};
        }
        for (int i = 0; i < p; i++)
        {
            int x1 = read(), y1 = read(), x2 = read(), y2 = read();
            cord[cnt++] = cor{x1, y1, 1, i};
            cord[cnt++] = cor{x2, y2, 2, i};
            qest[i] = qes{x1, x2};
        }
        sort(cord, cord + cnt, cmp);
        for (int i = 0; i < cnt; i++)
        {
            int x = cord[i].x, y = cord[i].y, id = cord[i].qid;
            if (cord[i].type == 0) update(1, x, x, getVal(x, y));
            else if (cord[i].type == 1) ans[id] = query(1, qest[id].x1, qest[id].x2);
            else ans[id] = query(1, qest[id].x1, qest[id].x2) - ans[id];
        }
        for (int i = 0; i < p; i++) printf("%d\n", ans[i]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35850147/article/details/102690827
今日推荐