zoukankan      html  css  js  c++  java
  • CF1093E Intersection of Permutations

    \(\text{Solution}\)

    很容易想到映射处理
    \(a\) 为基准,主要是因为 \(a\) 不修改
    然后就是要解决这么一个问题,带单点修改的二维数点
    考虑 \(CDQ\) 分治
    当前只考虑分治中心左边区间的修改操作对右边查询的贡献
    树状数组即可维护
    (第一道 \(CDQ\) 将动态问题转化为静态问题)

    \(\text{Code}\)

    #include <cstdio> 
    #include <algorithm>
    #define IN inline
    #define RE register
    using namespace std;
    
    const int N = 2e5 + 5;
    int n, m, cnt, qt, a[N], b[N], pos[N], ans[N];
    struct node{int ty, x, l, r, v, id;}Q[N * 11], q[N * 11];
    IN bool cmp(node a, node b){return a.x < b.x ? 1 : (a.x == b.x ? a.ty > b.ty : 0);}
    
    struct BIT{
    	int c[N];
    	IN int lowbit(int x){return x & (-x);}
    	IN void Add(int x, int v){for(; x <= n; x += lowbit(x)) c[x] += v;}
    	IN int getsum(int x){int s = 0; for(; x; x -= lowbit(x)) s += c[x]; return s;}
    	IN int Query(int l, int r){return getsum(r) - getsum(l - 1);}
    }T;
    
    void CDQ(int l, int r)
    {
    	if (l == r) return;
    	int mid = l + r >> 1; CDQ(l, mid), CDQ(mid + 1, r);
    	for(RE int k = l; k <= r; k++) q[k] = Q[k];
    	sort(Q + l, Q + mid + 1, cmp), sort(Q + mid + 1, Q + r + 1, cmp);
    	int j, i;
    	for(j = mid + 1, i = l; j <= r; j++)
    	if (Q[j].ty == 1)
    	{
    		for(; i <= mid && Q[i].x <= Q[j].x; ++i) if (Q[i].ty == 2) T.Add(Q[i].l, Q[i].r);
    		ans[Q[j].id] += T.Query(Q[j].l, Q[j].r) * Q[j].v;
    	}
    	for(RE int k = l; k < i; k++) if (Q[k].ty == 2) T.Add(Q[k].l, -Q[k].r);
    	for(RE int k = l; k <= r; k++) Q[k] = q[k];
    }
    
    int main()
    {
    	scanf("%d%d", &n, &m);
    	for(RE int i = 1; i <= n; i++) scanf("%d", &a[i]), pos[a[i]] = i;
    	for(RE int i = 1; i <= n; i++) scanf("%d", &b[i]), b[i] = pos[b[i]], Q[++cnt] = node{2, i, b[i], 1};
    	for(RE int i = 1, ty, l, r, x, y; i <= m; i++)
    	{
    		scanf("%d%d%d", &ty, &l, &r);
    		if (ty == 1)
    			scanf("%d%d", &x, &y), Q[++cnt] = node{1, y, l, r, 1, ++qt}, Q[++cnt] = node{1, x - 1, l, r, -1, qt};
    		else{
    			Q[++cnt] = node{2, l, b[l], -1}, Q[++cnt] = node{2, r, b[r], -1};
    			swap(b[l], b[r]), Q[++cnt] = node{2, l, b[l], 1}, Q[++cnt] = node{2, r, b[r], 1};
    		}
    	}
    	CDQ(1, cnt);
    	for(RE int i = 1; i <= qt; i++) printf("%d\n", ans[i]);
    }
    
  • 相关阅读:
    并发队列、线程池、锁
    JVM、垃圾收集器
    Socket网络编程
    Netty入门
    SpringCloud微服务负载均衡与网关
    Android监听耳机按键事件
    利用本地不同磁盘文件夹作为git远程仓库进行灾备
    chrome浏览器form中button每点击一次,form就会提交一次
    [企业路由器] 一对一NAT映射设置指导
    win7镜像自带IE9的卸载
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/15808002.html
Copyright © 2011-2022 走看看