zoukankan      html  css  js  c++  java
  • [SNOI2017]一个简单的询问

    题目

    写水题快乐一下

    显然(operatorname{get(l_1,r_1,x)} imes operatorname{get(l_2,r_2,x)})可以拆成
    (operatorname{pre(r_1,x)} imes operatorname{pre(r_2,x)}+operatorname{pre(l_1-1,x)} imes operatorname{pre(l_2-1,x)})减去(operatorname{pre(r_1,x)} imes operatorname{pre(l_2-1,x)}+operatorname{pre(r_2,x)} imes operatorname{pre(l_1-1,x)})

    (operatorname{pre(i,x)})表示([1,i])(x)出现次数

    显然我们把一个询问拆成四个,(operatorname{pre(l,x)} imes operatorname{pre(r,x)})变成一组询问(l,r)即可,直接大力莫队莽

    代码

    #include <bits/stdc++.h>
    #define re register
    #define LL long long
    inline int read() {
        char c = getchar();
        int x = 0;
        while (c < '0' || c > '9') c = getchar();
        while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - 48, c = getchar();
        return x;
    }
    int a[50005], tax[50005], tmp[50005];
    struct Ask {
        int l, r, o, rk;
    } q[200005];
    int n, m, Q, sz;
    LL ans, Ans[50005];
    inline int cmp(const Ask &A, const Ask &B) {
        if (A.l / sz == B.l / sz)
            return A.r < B.r;
        return A.l < B.l;
    }
    inline void del(int x, int o) {
        ans -= 1ll * tax[a[x]] * tmp[a[x]];
        tmp[a[x]] += o;
        ans += 1ll * tax[a[x]] * tmp[a[x]];
    }
    inline void add(int x, int o) {
        ans -= 1ll * tax[a[x]] * tmp[a[x]];
        tax[a[x]] += o;
        ans += 1ll * tax[a[x]] * tmp[a[x]];
    }
    int main() {
        n = read();
        for (re int i = 1; i <= n; i++) a[i] = read();
        Q = read();
        for (re int l1, l2, r1, r2, i = 1; i <= Q; i++) {
            l1 = read(), r1 = read(), l2 = read(), r2 = read();
            q[++m] = (Ask){ r1, r2, 1, i };
            if (l1 > 1 && l2 > 1)
                q[++m] = (Ask){ l1 - 1, l2 - 1, 1, i };
            if (l2 > 1)
                q[++m] = (Ask){ r1, l2 - 1, -1, i };
            if (l1 > 1)
                q[++m] = (Ask){ r2, l1 - 1, -1, i };
        }
        for (re int i = 1; i <= m; i++)
            if (q[i].l > q[i].r)
                std::swap(q[i].l, q[i].r);
        sz = n / (std::sqrt(m)) + 1;
        std::sort(q + 1, q + m + 1, cmp);
        for (re int l = 0, r = 0, i = 1; i <= m; i++) {
            while (r < q[i].r) add(++r, 1);
            while (l > q[i].l) del(l--, -1);
            while (l < q[i].l) del(++l, 1);
            while (r > q[i].r) add(r--, -1);
            Ans[q[i].rk] += 1ll * q[i].o * ans;
        }
        for (re int i = 1; i <= Q; i++) printf("%lld
    ", Ans[i]);
        return 0;
    }
    
  • 相关阅读:
    51 Nod 1086 多重背包问题(单调队列优化)
    51 Nod 1086 多重背包问题(二进制优化)
    51 Nod 1085 01背包问题
    poj 2559 Largest Rectangle(单调栈)
    51 Nod 1089 最长回文子串(Manacher算法)
    51 Nod N的阶乘的长度 (斯特林近似)
    51 Nod 1134 最长递增子序列(经典问题回顾)
    51 Nod 1020 逆序排列
    PCA-主成分分析(Principal components analysis)
    Python中cPickle
  • 原文地址:https://www.cnblogs.com/asuldb/p/11351891.html
Copyright © 2011-2022 走看看