• P3759 [TJOI2017]不勤劳的图书管理员 [树套树]


    树套树是什么啊我不知道/dk
    我只知道卡常数w

    // by Isaunoya
    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #pragma GCC optimize("Ofast")
    #pragma GCC optimize( 
    	"inline,-fgcse,-fgcse-lm,-fipa-sra,-ftree-pre,-ftree-vrp,-fpeephole2,-ffast-math,-fsched-spec,unroll-loops,-falign-jumps,-falign-loops,-falign-labels,-fdevirtualize,-fcaller-saves,-fcrossjumping,-fthread-jumps,-funroll-loops,-freorder-blocks,-fschedule-insns,inline-functions,-ftree-tail-merge,-fschedule-insns2,-fstrict-aliasing,-fstrict-overflow,-falign-functions,-fcse-follow-jumps,-fsched-interblock,-fpartial-inlining,no-stack-protector,-freorder-functions,-findirect-inlining,-fhoist-adjacent-loads,-frerun-cse-after-loop,inline-small-functions,-finline-small-functions,-ftree-switch-conversion,-foptimize-sibling-calls,-fexpensive-optimizations,inline-functions-called-once,-fdelete-null-pointer-checks")
    #include <bits/stdc++.h>
    using namespace std;
    #define rep(i, x, y) for (register int i = (x); i <= (y); ++i)
    #define Rep(i, x, y) for (register int i = (x); i >= (y); --i)
    using ll = long long;
    const int _ = 1 << 21;
    struct I {
        char fin[_], *p1 = fin, *p2 = fin;
        inline char gc() {
            return (p1 == p2) && (p2 = (p1 = fin) + fread(fin, 1, _, stdin), p1 == p2) ? EOF : *p1++;
        }
        inline I& operator>>(int& x) {
            bool sign = 1;
            char c = 0;
            while (c < 48) ((c = gc()) == 45) && (sign = 0);
            x = (c & 15);
            while ((c = gc()) > 47) x = (x << 1) + (x << 3) + (c & 15);
            x = sign ? x : -x;
            return *this;
        }
        inline I& operator>>(double& x) {
            bool sign = 1;
            char c = 0;
            while (c < 48) ((c = gc()) == 45) && (sign = 0);
            x = (c - 48);
            while ((c = gc()) > 47) x = x * 10 + (c - 48);
            if (c == '.') {
                double d = 1.0;
                while ((c = gc()) > 47) d = d * 0.1, x = x + (d * (c - 48));
            }
            x = sign ? x : -x;
            return *this;
        }
        inline I& operator>>(char& x) {
            do
                x = gc();
            while (isspace(x));
            return *this;
        }
        inline I& operator>>(string& s) {
            s = "";
            char c = gc();
            while (isspace(c)) c = gc();
            while (!isspace(c) && c != EOF) s += c, c = gc();
            return *this;
        }
    } in;
    struct O {
        char st[100], fout[_];
        signed stk = 0, top = 0;
        inline void flush() { fwrite(fout, 1, top, stdout), fflush(stdout), top = 0; }
        inline O& operator<<(int x) {
            if (top > (1 << 20))
                flush();
            if (x < 0)
                fout[top++] = 45, x = -x;
            do
                st[++stk] = x % 10 ^ 48, x /= 10;
            while (x);
            while (stk) fout[top++] = st[stk--];
            return *this;
        }
        inline O& operator<<(ll x) {
            if (top > (1 << 20))
                flush();
            if (x < 0)
                fout[top++] = 45, x = -x;
            do
                st[++stk] = x % 10 ^ 48, x /= 10;
            while (x);
            while (stk) fout[top++] = st[stk--];
            return *this;
        }
        inline O& operator<<(char x) {
            fout[top++] = x;
            return *this;
        }
        inline O& operator<<(string s) {
            if (top > (1 << 20))
                flush();
            for (char x : s) fout[top++] = x;
            return *this;
        }
    } out;
    #define pb emplace_back
    #define fir first
    #define sec second
    template <class T>
    inline void cmax(T& x, const T& y) {
        (x < y) && (x = y);
    }
    template <class T>
    inline void cmin(T& x, const T& y) {
        (x > y) && (x = y);
    }
    const int N = 5e4 + 10;
    const int mod = 1e9 + 7;
    int n, m, a[N], v[N], rt[N], ls[N << 8], rs[N << 8], Cnt = 0;
    struct SegMent {
        int val[N << 8];
        void upd(int& p, int l, int r, int pos, int v) {
            if (!p)
                p = ++Cnt;
            val[p] += v;
            if (l == r)
                return;
            int mid = l + r >> 1;
            (pos <= mid) ? upd(ls[p], l, mid, pos, v) : upd(rs[p], mid + 1, r, pos, v);
        }
        int qry(int p, int a, int b, int l, int r) {
            if (!p)
                return 0;
            if (a <= l && r <= b)
                return val[p];
            int mid = l + r >> 1, ans = 0;
            if (a <= mid)
                ans = qry(ls[p], a, b, l, mid);
            if (b > mid)
                ans += qry(rs[p], a, b, mid + 1, r);
            return ans % mod;
        }
        inline int low(const int& x) { return x & -x; }
        inline void upd(int x, int y, int k) {
            for (; x <= n; x += low(x)) upd(rt[x], 1, n, y, k);
        }
        inline ll qry(int l, int r, int a, int b) {
            ll ans = 0;
            for (; r; r ^= low(r)) {
                ans = (ans + qry(rt[r], a, b, 1, n)) % mod;
            }
            for (--l; l; l ^= low(l)) {
                ans = (ans - qry(rt[l], a, b, 1, n) + mod) % mod;
            }
            return ans;
        }
    } cnt, qwq;
    ll ans = 0;
    signed main() {
    #ifdef _WIN64
        freopen("testdata.in", "r", stdin);
    #endif
        in >> n >> m;
        rep(i, 1, n) in >> a[i] >> v[i];
        rep(i, 1, n) cnt.upd(i, a[i], 1), qwq.upd(i, a[i], v[i]);
        rep(i, 1, n) {
            ans = (ans + cnt.qry(i + 1, n, 1, a[i]) * v[i]) % mod;
            ans = (ans + qwq.qry(i + 1, n, 1, a[i])) % mod;
        }
        while (m--) {
            int x, y;
            in >> x >> y;
            if (x > y)
                swap(x, y);
            if (x == y) {
                out << ans << '
    ';
                continue;
            }
            ans = (ans +
                   (a[x] < a[y] ? 1 : -1) *
                       (2 * qwq.qry(x, y, min(a[x], a[y]) + 1, max(a[x], a[y]) - 1) +
                        (cnt.qry(x, y, min(a[x], a[y]) + 1, max(a[x], a[y]) - 1) + 1) * (v[x] + v[y])) %
                       mod +
                   mod) %
                  mod;
            ans = (ans + cnt.qry(x, y, 1, min(a[x], a[y]) - 1) * (v[y] - v[x]) % mod + mod) % mod;
            ans = (ans + cnt.qry(x, y, max(a[x], a[y]) + 1, n) * (v[x] - v[y]) % mod + mod) % mod;
            cnt.upd(x, a[x], -1), qwq.upd(x, a[x], -v[x]);
            cnt.upd(y, a[y], -1), qwq.upd(y, a[y], -v[y]);
            cnt.upd(x, a[y], 1), qwq.upd(x, a[y], v[y]);
            cnt.upd(y, a[x], 1), qwq.upd(y, a[x], v[x]);
            swap(a[x], a[y]), swap(v[x], v[y]);
            out << ans << '
    ';
        }
        return out.flush(), 0;
    }
    
  • 相关阅读:
    用Python实现的数据结构与算法:双端队列
    用Python实现的数据结构与算法:队列
    用Python实现的数据结构与算法:堆栈
    用Python实现的数据结构与算法:开篇
    用Markdown写博客
    一个简单的web.py论坛
    在OpenShift上托管web.py应用
    SQLite中的自增关键字:AUTO_INCREMENT、INTEGER PRIMARY KEY与AUTOINCREMENT
    【读书笔记】《HTTP权威指南》:Web Hosting
    【读书笔记】《HTTP权威指南》:Web Robots
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/12232994.html
Copyright © 2020-2023  润新知