zoukankan      html  css  js  c++  java
  • 【LG1975】[国家集训队]排队

    【LG1975】[国家集训队]排队

    题面

    洛谷

    题解

    又是一个偏序问题

    显然(CDQ)

    交换操作不好弄怎么办?

    可以看成两次删除两次插入

    排序问题要注意一下

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <vector> 
    using namespace std;
    namespace IO { 
        const int BUFSIZE = 1 << 20; 
        char ibuf[BUFSIZE], *is = ibuf, *it = ibuf; 
        inline char gc() { 
            if (is == it) it = (is = ibuf) + fread(ibuf, 1, BUFSIZE, stdin); 
    		return *is++; 
        } 
    } 
    inline int gi() {
        register int data = 0, w = 1;
        register char ch = 0;
        while (ch != '-' && (ch > '9' || ch < '0')) ch = IO::gc();
        if (ch == '-') w = -1 , ch = IO::gc();
        while (ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = IO::gc();
        return w * data;
    } 
    const int MAX_N = 22005; 
    struct Node { int x, y, z, w, id; } t[MAX_N << 2], tmp[MAX_N << 2]; 
    bool cmp_y(Node a, Node b) { return (a.y == b.y) ? (a.z < b.z) : (a.y < b.y); } 
    int N, M, tot, X[MAX_N], a[MAX_N], c[MAX_N], ans[MAX_N]; 
    inline int lb(int x) { return x & -x; } 
    void add(int x, int v) { while (x <= N) c[x] += v, x += lb(x); } 
    int sum(int x) { int res = 0; while (x > 0) res += c[x], x -= lb(x); return res; } 
    void Div(int l, int r) { 
    	if (l == r) return ; 
    	int mid = (l + r) >> 1; 
    	for (int i = l; i <= r; i++) 
    	    if (t[i].x <= mid) add(t[i].z, t[i].w); 
    	    else ans[t[i].id] += t[i].w * (sum(N) - sum(t[i].z)); 
    	for (int i = l; i <= r; i++) 
    	    if (t[i].x <= mid) add(t[i].z, -t[i].w); 
    	for (int i = r; i >= l; i--) 
    	    if (t[i].x <= mid) add(t[i].z, t[i].w); 
    	    else ans[t[i].id] += t[i].w * sum(t[i].z - 1); 
    	for (int i = l; i <= r; i++) if (t[i].x <= mid) add(t[i].z, -t[i].w); 
        int t1 = l - 1, t2 = mid; 
        for (int i = l; i <= r; i++) 
            if (t[i].x <= mid) tmp[++t1] = t[i]; 
            else tmp[++t2] = t[i]; 
        for (int i = l; i <= r; i++) t[i] = tmp[i]; 
        Div(l, mid); Div(mid + 1, r); 
    } 
    int main () { 
        N = gi(); 
        for (int i = 1; i <= N; i++) X[i] = a[i] = gi(); 
        sort(&X[1], &X[N + 1]); int size = unique(&X[1], &X[N + 1]) - X - 1; 
        for (int i = 1; i <= N; i++) a[i] = lower_bound(&X[1], &X[size + 1], a[i]) - X; 
        for (int i = 1; i <= N; i++) t[++tot] = (Node){tot, i, a[i], 1, 0}; 
        N = size; M = gi(); 
        for (int i = 1; i <= M; i++) { 
            int x = gi(), y = gi(); 
            t[++tot] = (Node){tot, x, a[x], -1, i}; 
            t[++tot] = (Node){tot, y, a[y], -1, i}; 
            t[++tot] = (Node){tot, x, a[y], +1, i}; 
            t[++tot] = (Node){tot, y, a[x], +1, i}; 
            swap(a[x], a[y]); 
        } 
        sort(&t[1], &t[tot + 1], cmp_y); 
        Div(1, tot); 
        printf("%d
    ", ans[0]); 
        for (int i = 1; i <= M; i++) printf("%d
    ", ans[i] += ans[i - 1]); 
        return 0; 
    } 
    
  • 相关阅读:
    Building Apache Thrift on CentOS 6.5
    ToStringBuilder 学习
    对List中对象的去重
    MyEclipse启动Tomcat服务器时老是跳到Debug调试上
    JS 实现点击展开菜单
    详解公钥、私钥、数字证书的概念 转载
    eclipse svn 忽略 target目录 等等... 我用的后边的方法 (转载)
    Log4j XML 配置
    JS完成改变新闻字体大中小的显示
    Javascript 简单学习
  • 原文地址:https://www.cnblogs.com/heyujun/p/10122091.html
Copyright © 2011-2022 走看看