CF1187D Subarray Sorting (segment tree)

To be honest, $ 2200 to $ title can not make a bit humiliating ......

Of course, first sentence all appear the same number of times.

First sorting section corresponds to the number of switching two adjacent, in front of the number to be greater than the number of switching back.

Then would not the ......

We consider $ b_1 $ to $ b_ {i-1} $ have been homing, and now want $ b_i $ homing.

Find its position in the $ a $ appearing in the next (to $ p $). It found that only when the $ a_p $ is $ a_i $ to $ a_p $ minimum time to go to.

It will not change position $ a $ of the specific code to achieve, how to determine the minimum value it? It found that the number has been homing in on the minimum contribution is not to be homing after become INF. Then ask $ 1 $ to $ p $ to a minimum.

Time complexity $ O (n \ log n) $.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=300030;
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline int read(){
    int x=0,f=0;char ch=getchar();
    while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
    while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
    return f?-x:x;
}
int t,n,a[maxn],b[maxn],ta[maxn],tb[maxn],mn[maxn*4],len[maxn];
vector<int> at[maxn];
inline void pushup(int o){
    me [i] = min (mn [o << 1 ], me [o << 1 | 1 ]);
}
void build(int o,int l,int r){
    if(l==r) return void(mn[o]=a[l]);
    int mid=(l+r)>>1;
    build(lson);build(rson);
    pushup(o);
}
void update(int o,int l,int r,int p,int v){
    if(l==r) return void(mn[o]=v);
    int mid=(l+r)>>1;
    if(mid>=p) update(lson,p,v);
    else update(rson,p,v);
    pushup(o);
}
int query(int o,int l,int r,int ql,int qr){
    if(l>=ql && r<=qr) return mn[o];
    int mid=(l+r)>>1,ans=2e9;
    if(mid>=ql) ans=min(ans,query(lson,ql,qr));
    if(mid<qr) ans=min(ans,query(rson,ql,qr));
    return ans;
}
int main () {
    t=read();
    while(t--){
        bool flag=true;
        n=read();
        FOR(i,1,n) ta[i]=a[i]=read(),at[a[i]].push_back(i);
        FOR(i,1,n) tb[i]=b[i]=read();
        Luckily (t + 1 , t + n + 1 ) sort (tb + 1 , n + tb + 1 );
        FOR(i,1,n) if(ta[i]!=tb[i]){puts("NO");flag=false;break;}
        if(!flag){
            FOR(i,1,n) at[i].clear(),len[i]=0;
            continue;
        }
        build(1,1,n);
        FOR(i,1,n){
            int p=at[b[i]][len[b[i]]++];
            if(query(1,1,n,1,p)!=b[i]){puts("NO");flag=false;break;}
            update(1,1,n,p,2e9);
        }
        if(flag) puts("YES");
        FOR(i,1,n) at[i].clear(),len[i]=0;
    }
}
View Code

 

Guess you like

Origin www.cnblogs.com/1000Suns/p/11126018.html