zoukankan      html  css  js  c++  java
  • [国家集训队]排队 [cdq分治]

    题面

    洛谷

    和动态逆序对那道题没有什么区别
    把一个交换换成两个删除和两个插入

    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    using namespace std;
    const int N = 1e5 + 5;
    const double eps = 1e-9;
    const int inf = 0x3f3f3f3f;
    typedef pair<int, int> PII;
    typedef pair<double, int> PDI;
    struct Node{
        int x, y, z, d, cnt;	
    }node[N];
    bool rule_yzx(Node x, Node y){
        if(x.y != y.y) return x.y < y.y;	
    	if(x.z != y.z) return x.z < y.z;
    	return x.x < y.x;
    }
    int n, m, nsize, a[N], b[N];
    int tim, dfn[N];
    long long ans[N];
    struct BIT{
        int w[N];
        void ins(int x, int d){while(x<=n){w[x] += d; x += x & -x;}}	
    	int qry(int x){int res = 0; while(x){res += w[x]; x -= x & -x;}return res;}
    	void print(){for(int i = 1; i <= n; ++i) printf("%d", w[i]); printf("
    ");}
    }bit;
    	
    inline void add(int x1, int x2, int x3, int x4){
        ++nsize;
        node[nsize].x = x1, node[nsize].y = x2, node[nsize].z = x3, node[nsize].d = x4;
    }
    
    void cdq(int L, int R){
        if(L == R) return ;
    	int mid = L + ((R - L) >> 1);
        cdq(L, mid); cdq(mid + 1, R);	
        sort(node + L, node + mid + 1, rule_yzx);
        sort(node + mid + 1, node + R + 1, rule_yzx);
        int j = L; 
        for(int i = mid + 1; i <= R; ++i){
    		while(j <= mid && node[j].y <= node[i].y){
    			bit.ins(node[j].z, node[j].d); ++j;
    		}
    		node[i].cnt += node[i].d * (bit.qry(n) - bit.qry(node[i].z));
    	}
    	//printf("L %d R %d
    ", L, R);
    	//bit.print();
    	while(j > L){--j; bit.ins(node[j].z, -node[j].d);}
    	j = mid;
    	for(int i = R; i >= mid + 1; --i){
    	    while(j >= L && node[j].y >= node[i].y){
    		    bit.ins(node[j].z, node[j].d); --j;	
    		}	
    		node[i].cnt += node[i].d * bit.qry(node[i].z - 1);
    	}
    	while(j < mid){++j; bit.ins(node[j].z, -node[j].d);} 
    }
    
    int main() {
    	scanf("%d", &n);
    	for(int i = 1; i <= n; ++i){
    	    scanf("%d", &a[i]); b[i] = a[i];
    	}
    	sort(b + 1, b + n + 1);
    	for(int i = 1; i <= n; ++i){
    		a[i] = (lower_bound(b + 1, b + n + 1, a[i]) - b);
    		add(0, i, a[i], 1);
    		//printf("%d %d %d
    ", node[i].x, node[i].y, node[i].z);
    	}
    	scanf("%d", &m);
    	for(int i = 1, x, y; i <= m; ++i){
    		scanf("%d%d", &x, &y);
    		add(++tim, x, a[x], -1);
    		add(++tim, y, a[y], -1);
    		swap(a[x], a[y]);
    		add(++tim, x, a[x], 1);
    		add(++tim, y, a[y], 1);
    		dfn[i] = tim;
    	}
    	//for(int i = 1; i <= nsize; ++i) printf("%d %d %d
    ", node[i].x, node[i].y, node[i].z);
        //已经是升序了
    	cdq(1, nsize);
    	for(int i = 1; i <= nsize; ++i){
    	    //printf("%d %d %d %d
    ", node[i].x, node[i].y, node[i].z, node[i].cnt);	
    		ans[node[i].x] += node[i].cnt;
    	} 
    	for(int i = 1; i <= tim; ++i) ans[i] += ans[i - 1];
    	for(int i = 0; i <= m; ++i) printf("%d
    ", ans[dfn[i]]); 
    	system("PAUSE");
        return 0;
    }
    
  • 相关阅读:
    Linux实战教学笔记14:用户管理初级(上)
    上传文件到服务器指定位置 & 从服务器指定位置下载文件
    flume读取日志文件并存储到HDFS
    Kafka
    Eclipse获取工作空间跟运行空间
    Java开发webservice的几种方式
    获取.properties配置文件属性值
    数组合并
    字符串对象跟xml格式的转换
    文件压缩跟解压(本地&Linux服务器)
  • 原文地址:https://www.cnblogs.com/hjmmm/p/10649845.html
Copyright © 2011-2022 走看看