[树状数组][权值线段树] Codeforces 1093E Intersection of Permutations
Posted comfortable
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[树状数组][权值线段树] Codeforces 1093E Intersection of Permutations相关的知识,希望对你有一定的参考价值。
题目描述
You are given two permutations aa and bb , both consisting of nn elements. Permutation of nn elements is such a integer sequence that each value from 11 to nn appears exactly once in it.
You are asked to perform two types of queries with them:
- 1~l_a~r_a~l_b~r_b1 la? ra? lb? rb? — calculate the number of values which appear in both segment [l_a; r_a][la?;ra?] of positions in permutation aa and segment [l_b; r_b][lb?;rb?] of positions in permutation bb ;
- 2~x~y2 x y — swap values on positions xx and yy in permutation bb .
Print the answer for each query of the first type.
It is guaranteed that there will be at least one query of the first type in the input.
输入输出格式
输入格式:
The first line contains two integers nn and mm ( 2 \le n \le 2 \cdot 10^52≤n≤2⋅105 , 1 \le m \le 2 \cdot 10^51≤m≤2⋅105 ) — the number of elements in both permutations and the number of queries.
The second line contains nn integers a_1, a_2, \dots, a_na1?,a2?,…,an? ( 1 \le a_i \le n1≤ai?≤n ) — permutation aa . It is guaranteed that each value from 11 to nn appears in aa exactly once.
The third line contains nn integers b_1, b_2, \dots, b_nb1?,b2?,…,bn? ( 1 \le b_i \le n1≤bi?≤n ) — permutation bb . It is guaranteed that each value from 11 to nn appears in bb exactly once.
Each of the next mm lines contains the description of a certain query. These are either:
- 1~l_a~r_a~l_b~r_b1 la? ra? lb? rb? ( 1 \le l_a \le r_a \le n1≤la?≤ra?≤n , 1 \le l_b \le r_b \le n1≤lb?≤rb?≤n );
- 2~x~y2 x y ( 1 \le x, y \le n1≤x,y≤n , x \ne yx≠y ).
输出格式:
Print the answers for the queries of the first type, each answer in the new line — the number of values which appear in both segment [l_a; r_a][la?;ra?] of positions in permutation aa and segment [l_b; r_b][lb?;rb?] of positions in permutation bb .
输入输出样例
6 7 5 1 4 2 3 6 2 5 3 1 4 6 1 1 2 4 5 2 2 4 1 1 2 4 5 1 2 3 3 5 1 1 6 1 2 2 4 1 1 4 4 1 3
说明
Consider the first query of the first example. Values on positions [1; 2][1;2] of aa are [5, 1][5,1] and values on positions [4; 5][4;5] of bb are [1, 4][1,4] . Only value 11 appears in both segments.
After the first swap (the second query) permutation bb becomes [2, 1, 3, 5, 4, 6][2,1,3,5,4,6] .
After the second swap (the sixth query) permutation bb becomes [5, 1, 3, 2, 4, 6][5,1,3,2,4,6] .
题解
- 这就是个二维点数问题,直接上树套树就好了
代码
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 using namespace std; 5 const int N=2e5+10,M=1e6*40; 6 int n,m,cnt,top,a[N],b[N],d[N],st[N],root[N]; 7 struct node int num,ch[2]; e[M]; 8 int lowbit(int x) return (x)&(-x); 9 void add(int &d,int x,int y,int l,int r) 10 11 if (!d) d=top?st[top--]:++cnt; e[d].num+=y; 12 if (l==r) return; 13 int mid=l+r>>1; 14 if (x<=mid) add(e[d].ch[0],x,y,l,mid); else add(e[d].ch[1],x,y,mid+1,r); 15 if (!e[d].num) st[++top]=d,d=0; 16 17 void add(int x,int y,int v) for (;x<=n;x+=lowbit(x)) add(root[x],y,v,1,n); 18 int query(int d,int l,int r,int L,int R) 19 20 if (!d) return 0; 21 if (L<=l&&r<=R) return e[d].num; 22 int mid=l+r>>1,tot=0; 23 if (L<=mid) tot+=query(e[d].ch[0],l,mid,L,R); 24 if (R>mid) tot+=query(e[d].ch[1],mid+1,r,L,R); 25 return tot; 26 27 int query(int L,int R,int l,int r) 28 29 int ans=0; 30 for (int i=L-1;i;i-=lowbit(i)) ans-=query(root[i],1,n,l,r); 31 for (int i=R;i;i-=lowbit(i)) ans+=query(root[i],1,n,l,r); 32 return ans; 33 34 int main() 35 36 scanf("%d%d",&n,&m); 37 for (int i=1;i<=n;i++) scanf("%d",&a[i]),d[a[i]]=i; 38 for (int i=1,x;i<=n;i++) scanf("%d",&x),b[i]=d[x]; 39 for (int i=1;i<=n;i++) add(i,b[i],1); 40 for (int l,r,L,R,op;m;m--) 41 42 scanf("%d",&op); 43 if (op==1) scanf("%d%d%d%d",&L,&R,&l,&r),printf("%d\n",query(l,r,L,R)); 44 else scanf("%d%d",&l,&r),add(l,b[l],-1),add(r,b[r],-1),add(l,b[r],1),add(r,b[l],1),swap(b[l],b[r]); 45 46
以上是关于[树状数组][权值线段树] Codeforces 1093E Intersection of Permutations的主要内容,如果未能解决你的问题,请参考以下文章
P2617 Dynamic Rankings (动态开点权值线段树 + 树状数组)