(线段树操作)

匿名 (未验证) 提交于 2019-12-02 23:47:01

https://codeforces.com/contest/1187/problem/D

题意:选取a序列的一段【l,r】将选中的区间按非降排序。问能否经过若干次操作后形成b序列;

分析:b序列的数的总类及各个类的数目一定要与a序列相同;

   对b的每个位置的值,找到与之相同的a序列中还没有被用的位置nowpos,然后判断1到nowpos的最小值是否等于b序列的当前值,再将该位置修改为无效值;

#include<bits/stdc++.h> using namespace std; const int M=3e5+5; const int inf=0x3f3f3f3f; int tree[M<<2],a[M],b[M],aa[M],bb[M],ll[M]; vector<int>pos[M]; void up(int root){     tree[root]=min(tree[root<<1],tree[root<<1|1]); } void build(int root,int l,int r){     if(l==r){         tree[root]=a[l];         return ;     }     int midd=(l+r)>>1;     build(root<<1,l,midd);     build(root<<1|1,midd+1,r);     up(root); } int query(int L,int R,int root,int l,int r){     if(L<=l&&r<=R){         return tree[root];     }     int midd=(l+r)>>1;     int ans=inf;     if(L<=midd)         ans=min(ans,query(L,R,root<<1,l,midd));     if(R>midd)         ans=min(ans,query(L,R,root<<1|1,midd+1,r));     return ans; } void update(int nowpos,int x,int root,int l,int r){     if(l==r){         tree[root]=x;         return ;     }     int midd=(l+r)>>1;     if(midd>=nowpos)         update(nowpos,x,root<<1,l,midd);     else         update(nowpos,x,root<<1|1,midd+1,r);     up(root); } int main(){     int t;     scanf("%d",&t);     while(t--){         int n;         scanf("%d",&n);         for(int i=0;i<=n;i++){             pos[i].clear();             ll[i]=0;         }         for(int i=1;i<=n;i++){             scanf("%d",&a[i]);             pos[a[i]].push_back(i);             aa[i]=a[i];         }         for(int i=1;i<=n;i++){             scanf("%d",&b[i]);             bb[i]=b[i];         }         sort(aa+1,aa+1+n);         sort(bb+1,bb+1+n);         int flag=0;         for(int i=1;i<=n;i++){             if(aa[i]!=bb[i]){                 flag=1;                 break;             }         }         if(flag){             puts("NO");             continue;         }         build(1,1,n);        /* for(int i=1;i<=n*2;i++)             cout<<tree[i]<<" ";*/         for(int i=1;i<=n;i++){             int ch=b[i];            // cout<<ch<<endl;             if(flag)                 continue;             int cur_pos=pos[ch][ll[ch]++];             if(ch!=query(1,cur_pos,1,1,n)){                 flag=1;              }          //   cout<<"!!"<<endl;             update(cur_pos,inf,1,1,n);         }         if(flag)             puts("NO");         else             puts("YES");       }     return 0; }
View Code

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!