[树状数组][权值线段树] 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 .

 

输入输出样例

输入样例#1: 
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
输出样例#1: 
1
1
1
2
0

说明

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 }

 

上一篇:Photoshop美女照片动漫写轮眼


下一篇:C#行列式计算程序