zoukankan      html  css  js  c++  java
  • [树状数组][权值线段树] 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^52n2105 , 1 le m le 2 cdot 10^51m2105 ) — 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 n1ain ) — 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 n1bin ) — 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 n1laran , 1 le l_b le r_b le n1lbrbn );
    • 2~x~y2 x y ( 1 le x, y le n1x,yn , x e yxy ).

    输出格式:

    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
    ",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 }
  • 相关阅读:
    全选、反选和不选
    树状图
    年月日选择器
    细谈HTML5
    再谈HTML
    FlashFXP 破解代码
    文件上传示例
    PHP聊天室框架
    JS判断是否来自手机移动端的访问,并跳转
    JQUERY知识总结
  • 原文地址:https://www.cnblogs.com/Comfortable/p/11206582.html
Copyright © 2011-2022 走看看