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

    [CF1093E]Intersection of Permutations

    题目大意:

    给定两个长度为(n(nle2 imes10^5))的排列(A,B)(m(mle2 imes10^5))次操作,操作分为以下两种:

    1. 询问有多少同时在(A_{[x,y]})(B_{[l,r]})中出现的数。
    2. 交换(B_x)(B_y)

    思路:

    (v[a[i]]=i,b[i]=v[b[i]]),这样询问就变成([x,y])中有多少数在(B_{[l,r]})中出现。

    用树状数组+平衡树维护每个区间出现哪些数,询问时在平衡树中查找排名即可。

    源代码:

    #include<cstdio>
    #include<cctype>
    #include<climits>
    #include<ext/pb_ds/tree_policy.hpp>
    #include<ext/pb_ds/assoc_container.hpp>
    inline int getint() {
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return x;
    }
    const int N=2e5+1;
    int n,v[N],a[N];
    using namespace __gnu_pbds;
    using RBTree=tree<int,null_type,std::less<int>,rb_tree_tag,tree_order_statistics_node_update>;
    class FenwickTree {
    	private:
    		RBTree t[N];
    		int lowbit(const int &x) const {
    			return x&-x;
    		}
    		int query(int p,const int &x,const int &y) const {
    			int ret=0;
    			for(;p;p-=lowbit(p)) {
    				const int L=*t[p].lower_bound(x);
    				const int R=*std::prev(t[p].upper_bound(y));
    				if(L<=R) ret+=t[p].order_of_key(R)-t[p].order_of_key(L)+1;
    			}
    			return ret;
    		}
    	public:
    		void init() {
    			for(register int i=1;i<=n;i++) {
    				t[i].insert(INT_MIN);
    				t[i].insert(INT_MAX);
    			}
    		}
    		void insert(int p,const int &x) {
    			for(;p<=n;p+=lowbit(p)) {
    				t[p].insert(x);
    			}
    		}
    		void erase(int p,const int &x) {
    			for(;p<=n;p+=lowbit(p)) {
    				t[p].erase(x);
    			}
    		}
    		int query(const int &l,const int &r,const int &x,const int &y) const {
    			return query(r,x,y)-query(l-1,x,y);
    		}
    };
    FenwickTree t;
    int main() {
    	n=getint();
    	const int m=getint();
    	for(register int i=1;i<=n;i++) {
    		v[getint()]=i;
    	}
    	for(register int i=1;i<=n;i++) {
    		a[i]=v[getint()];
    	}
    	t.init();
    	for(register int i=1;i<=n;i++) {
    		t.insert(i,a[i]);
    	}
    	for(register int i=0;i<m;i++) {
    		const int opt=getint(),x=getint(),y=getint();
    		if(opt==1) {
    			const int l=getint(),r=getint();
    			printf("%d
    ",t.query(l,r,x,y));
    		}
    		if(opt==2) {
    			t.erase(x,a[x]);
    			t.erase(y,a[y]);
    			std::swap(a[x],a[y]);
    			t.insert(x,a[x]);
    			t.insert(y,a[y]);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    安卓监听帧动画结束
    零基础学python-13.4 文件上使用列表解析与列表解析扩展
    零基础学python-13.3 列表解析简介与步骤分解
    零基础学python-13.2 手动迭代:iter和next
    零基础学python-13.1 迭代器简介与文件迭代器
    零基础学python-12.6 使用for和zip来并行使用多个序列
    零基础学python-12.5 修改列表的误区以及使用for和range修改列表
    零基础学python-12.4 while、for与range联合使用
    零基础学python-12.3 for循环
    零基础学python-12.2 关键字pass,else,break,continue
  • 原文地址:https://www.cnblogs.com/skylee03/p/10372903.html
Copyright © 2011-2022 走看看