zoukankan      html  css  js  c++  java
  • Codeforces1093E_Intersection of Permutations

    题意

    给定两个排列a和b,两种操作,交换b_i和b_j,询问a[l_a...r_a]和b[l_b...r_b]有多少个数相同。

    分析

    • 由于给的是排列,保证b的每个数都有a的对应,构造数组c,c[i]表示b[i]在a数组中的位置。
    • 所以询问就变成询问c[l_b...r_b]中有多少个值域为[l_a...r_b]的数,树套树...
    • 内层的权值线段树动态开点一不小心就RE在第22个点,写了可回收的方式才过。
    • 代码10分钟,debug两节课...

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=2e5+50;
    int n,m,tr[N],a[N],p[N],b[N],c[N],o,la,ra,lb,rb,xi,yi,x[N],y[N],c1,c2,sta[N],top;
    struct VST{
    #define mid (l+r)/2
        int tot,sum[N*180],ls[N*180],rs[N*180];
        //回收节点
        int newnode(){
    	    int p=top?sta[--top]:++tot;
    	    ls[p]=rs[p]=sum[p]=0;
    	    return p;
        }
        void update(int &x,int l,int r,int v,int add){
            if(!x){
                x=newnode();
            }
            sum[x]+=add;
            if(l<r){
                if(v<=mid){
                    update(ls[x],l,mid,v,add);
                }else{
                    update(rs[x],mid+1,r,v,add);
                }
            }
            //回收节点
            if(!sum[x]){
                sta[top++]=x;
                x=0;
            }
        }
        int query(int l,int r,int k){
            if(k==0){
                return 0;
            }
            if(r<=k){
                int ans=0;
                for(int i=1;i<=c1;i++){
                    ans-=sum[x[i]];
                }
                for(int i=1;i<=c2;i++){
                    ans+=sum[y[i]];
                }
                return ans;
            }
            if(k<=mid){
                for(int i=1;i<=c1;i++){
                    x[i]=ls[x[i]];
                }
                for(int i=1;i<=c2;i++){
                    y[i]=ls[y[i]];
                }
                return query(l,mid,k);
            }else{
                int ans=0;
                for(int i=1;i<=c1;i++){
                    ans-=sum[ls[x[i]]];
                    x[i]=rs[x[i]];
                }
                for(int i=1;i<=c2;i++){
                    ans+=sum[ls[y[i]]];
                    y[i]=rs[y[i]];
                }
                return ans+query(mid+1,r,k);
            }
        }
    }ac;
    struct BIT{
        int lowbit(int x){
            return x&(-x);
        }
        void update(int i,int x){
            int k=c[i];
            while(i<=n){
                ac.update(tr[i],1,n,k,x);
                i+=lowbit(i);
            }
        }
        int query(int l,int r,int xi,int yi){
            c1=c2=0;
            for(int i=l-1;i;i-=lowbit(i)){
                x[++c1]=tr[i];
            }
            for(int i=r;i;i-=lowbit(i)){
                y[++c2]=tr[i];
            }
            int R=ac.query(1,n,yi);
            c1=c2=0;
            for(int i=l-1;i;i-=lowbit(i)){
                x[++c1]=tr[i];
            }
            for(int i=r;i;i-=lowbit(i)){
                y[++c2]=tr[i];
            }
            int L=ac.query(1,n,xi-1);
            return R-L;
        }
    }bit;
    int main(){
        // freopen("in.txt","r",stdin);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            p[a[i]]=i;
        }
        for(int i=1;i<=n;i++){
            scanf("%d",&b[i]);
            c[i]=p[b[i]];
            bit.update(i,1);
        }
        for(int i=1;i<=m;i++){
            scanf("%d",&o);
            if(o==1){
                scanf("%d%d%d%d",&la,&ra,&lb,&rb);
                int ans=bit.query(lb,rb,la,ra);
                printf("%d
    ",ans);
            }else if(o==2){
                scanf("%d%d",&xi,&yi);
                bit.update(xi,-1);
                bit.update(yi,-1);
                swap(c[xi],c[yi]);
                bit.update(xi,1);
                bit.update(yi,1);
            }
        }
        return 0;
    }
  • 相关阅读:
    写了一个单链表的代码,而且支持反转链表,分组反转链表
    【Redis】redis分布式锁(二)
    【Redis】redis分布式锁(一)
    【Flutter】跟着flutter教程学着写了一个简单的Demo
    【Zookeeper】Zookeeper集群环境搭建
    【TDengine】TDengine初探
    【Shell】一个可以服务拉起、停止和重启的shell脚本
    【Linux】xftp报“找不到匹配的outgoing encryption算法”的错误
    【Linux】Ubuntu如何开启ftp服务器
    【Jenkins】使用Jenkins编译打包后自动部署项目
  • 原文地址:https://www.cnblogs.com/zxcoder/p/11509535.html
Copyright © 2011-2022 走看看