2016多校总结---hdu5821Ball

新套路get ; 

首先要判断a数组可以不可以到达b数组,如果是1-n那么就是排序,然后看ab相不相等。。。

但是这个是部分。。
这里有两点关键点:

1.如果有三个1.,位置在b数组中是pa < pb < pc ; 那么。由a -> b如果可以到达,那么一定存在一种方法:是在a中依次递增的1分别到依次递增的b数组。

例如:

1 1 0 0 1 0 0 

0 0 1 1 0 0 1

那么一定是a中第一个1到达b中第一个1 , 第二个到第二个。

因为这个是最可能的方法。如果其他的可以到达,那么这个一定可以到达。

这样对于a中的数据。使用b中的位置重新编码。这样b数组就是严格递增的。

这样,就可以做出了。

把每一个区间排序。在比较b和a是否相等/因为这样可以得到最小的a可以交换的字典序最小的序列。

#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#pragma comment(linker,"/STACK:102400000,102400000")

using namespace std;
#define   MAX         1000005
#define   MAXN        2000005
#define   maxnode     500010
#define   sigma_size  30
#define   lson        l,m,rt<<1
#define   rson        m+1,r,rt<<1|1
#define   lrt         rt<<1
#define   rrt         rt<<1|1
#define   mid         int m=(r+l)>>1
#define   LL          long long
#define   ull         unsigned long long
#define   mem0(x)     memset(x,0,sizeof(x))
#define   mem1(x)     memset(x,-1,sizeof(x))
#define   meminf(x)   memset(x,INF,sizeof(x))
#define   lowbit(x)   (x&-x)
#define   S(n)        scanf("%d",&n)
#define   P(n)        printf("%d ",n)
#define   PN(n)       printf("%d\n",n)
#define   FP(k)       freopen(k , "r" ,stdin)
#define   RPTI(s , n) for(int i=s;i<n;i++)
#define   RPTJ(s , n) for(int j=s;j<n;j++)
#define   RPTK(s , n) for(int k=s;k<n;k++)
#define   RPTL(s , n) for(int l=s;l<n;l++)
const LL     mod   = 1000000;
///const int    prime = 999983;
const int    INF   = 0x3f3f3f3f;
const int    INFF  = 1e9;
const double pi    = 3.141592653589793;
const double inf   = 1e18;
const double eps   = 1e-10;
inline int read_int(){
    int ret=0;
    char tmp;
    while(!isdigit(tmp=getchar()));
    do{
        ret=(ret<<3)+(ret<<1)+tmp-'0';
    }
    while(isdigit(tmp=getchar()));
    return ret;
}
/*******************************************/
typedef long long ll ;
const int moddd = 1e9 + 7 ;
int a[1005] ;
int b[1006] ;
int main(){
    int T ; scanf("%d" , &T) ;
    while(T--){
        queue <int> q[1005] ;
        int n , m; scanf("%d%d" , &n , &m) ;
        for(int i=1;i<=n;i++) scanf("%d" , &a[i]) ;
        for(int j=1;j<=n;j++){
            scanf("%d" , &b[j]) ;
            q[b[j]].push(j) ;
        }
        bool ok = true ;
        for(int i=1;i<=n;i++){
            if(q[a[i]].empty()) {
                ok = false ;///printf("empty = %d\n" , i) ;
                break ;
            }
            int tmp = a[i] ;
            a[i] = q[a[i]].front() ;
            q[tmp].pop() ;
        }
        for(int i=0;i<m;i++){
            int ta ,tb ;
            scanf("%d%d" , &ta ,&tb) ;
            sort(a+ta , a+tb+1) ;
        }
        for(int i=0;i<1005;i++) if(!q[i].empty()) ok = false ;
        for(int i=1;i<=n&&ok;i++){
            if(a[i] != i) ok = false ;
        }
        if(ok == true) printf("Yes\n") ;
        else printf("No\n") ;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值