Codeforces Educational Codeforces Round 56 (Rated for Div. 2) 1093E. Intersection of Permutations

版权声明:希望大家转载的时候把公式转载好一点QAQ,我就公式打得很辛苦了... https://blog.csdn.net/Myriad_Dreamin/article/details/85035454

求区间 a [ l , r ] a[l,r] b [ x , y ] b[x,y] 的数字出现了多少个。
因为 a , b a,b 均是排列,所以区间数字分布具有可加性。
所以分块+树状数组,时间复杂度约为 O ( n 3 / 2 lg n ) 2 e 5 × 5 e 2 × 20 = 2 e 9 \mathrm{O}(n^{3/2}\lg n)\approx 2e5\times 5e2\times 20=2e9 .
因为常数较大,所以 B l o c k = n Block=\sqrt{n} 不一定能过,通过卡 n \sqrt{n} 两侧枚举的时间可过。

#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <cctype>
#include <cstring>
#define lowbit(_x) ((_x)&-(_x))
using namespace std;
const int BufferSize=1<<16;
char buffer[BufferSize],*head,*tail;
inline char GET_CHAR(){
	if(head==tail){
		int l=fread(buffer,1,BufferSize,stdin);
		tail=(head=buffer)+l;
		if(head==tail)return EOF;
	}
	return *head++;
}
inline int READ(){
	int x=0,f=1;char c=GET_CHAR();
	for(;!isdigit(c);c=GET_CHAR()){
		if(c==EOF)return EOF;
		if(c=='-')f=-1;
	}
	for(;isdigit(c);c=GET_CHAR())x=(((x<<2)+x)<<1)+c-'0';
	return x*f;
}
const int N=200505,sqrtN=650;
int ref[N+5],bit[405][N+5];
int A[N+5],B[N+5],ra[N+5],rb[N+5],n;
void add(int *bit,int x,int v){
    while(x<=n){
        bit[x]+=v;
        x+=lowbit(x);
    }
    return ;
}
int sum(int *bit,int x){
    int res=0;
    while(x>0){
        res+=bit[x];
        x-=lowbit(x);
    }
    return res;
}
int Sum(int *bit,int l,int r){
    return sum(bit,r)-sum(bit,l-1);
}
int main(){
    n=READ();
    int m=READ();
    for(int i=sqrtN;i<=n;i++){
        ref[i]=ref[i-sqrtN]+1;
    }
    for(int i=1;i<=n;i++){
        A[i]=READ();
        ra[A[i]]=i;
    }
    for(int i=1;i<=n;i++){
        B[i]=READ();
        rb[B[i]]=i;
        add(bit[ref[ra[B[i]]]],i,1);
    }
    while(m--){
        int o=READ();
        if(o==1){
            int a,b,c,d;
            a=READ();b=READ();c=READ();d=READ();
            int t=ref[a]+1;
            int res=0;
            while(ref[a]<t&&a<=b){
                if(c<=rb[A[a]]&&rb[A[a]]<=d)res++;
                a++;
            }
            t=ref[b];
            while(ref[a]<t&&a<=b){
                res+=Sum(bit[ref[a]],c,d);
                a+=sqrtN;
            }
            while(a<=b){
                if(c<=rb[A[a]]&&rb[A[a]]<=d)res++;
                a++;
            }
            printf("%d\n",res);
        }
        else{
            int a,b;
            a=READ();b=READ();
            add(bit[ref[ra[B[a]]]],a,-1);
            add(bit[ref[ra[B[b]]]],b,-1);
            add(bit[ref[ra[B[a]]]],b,1);
            add(bit[ref[ra[B[b]]]],a,1);
            swap(B[a],B[b]);
            swap(rb[B[a]],rb[B[b]]);
        }
    }
    //system("pause");
}

猜你喜欢

转载自blog.csdn.net/Myriad_Dreamin/article/details/85035454