题目链接
标签:数论、逆序对、思维
思路1:先看A、B数组元素的范围,容易想到数组元素肯定会作为其他数组下标来判断两数组中各种数字出现的次数是否相同(其实sort之后一个个判断是否相等也可以),以及是否有数字出现了两次及以上。
思路2:题目给定的操作是每次选三个相连的数字进行逆时针旋转,我们只需要利用数组逆序对的奇偶性来判断,分为两种情况:
a、如果每种数字只出现一次,那么该操作不会改变数组的逆序对个数的奇偶性,如果奇偶性一样,则可以通过旋转来使得A、B相同
b、如果某种数字出现了两次及以上,那么我们可以利用该种数字来改变数组逆序对个数的奇偶性,所以必定可以通过旋转来使得A、B相同
代码:
#include<bits/stdc++.h>
#define rep(i,a,b) for(auto i = (a); i <= (b); ++i)
#define dep(i,a,b) for(auto i = (a); i >= (b); --i)
#define endl '\n'
#define debug(x) cout<<#x<<"="<<(x)<<endl;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
const int N = 2e5 + 10;
const int mod = 1e9 + 10;
const int inf = 1e9;
string yes = "yes\n",no = "no\n";
inline ll add(ll a,ll b){
return (a+=b)>=mod?a-mod:a;}
inline ll sub(ll a,ll b){
return (a-=b)<0?a+mod:a;}
inline ll mul(ll a,ll b){
return 1ll*a*a%mod;}
int n,a[N],b[N],c[N],d[N];
void AC(){
bool fg = 1,tw = 0;
cin >> n;
rep(i,1,n){
cin>>a[i];c[a[i]]++;}
rep(i,1,n){
cin>>b[i];d[b[i]]++;}
rep(i,1,5000){
if(c[i]!=d[i])fg = 0;
if(c[i] > 1)tw = 1;
}
int cnt1 = 0,cnt2 = 0;
rep(i,1,n){
rep(j,1,i-1){
if(a[j] > a[i])cnt1^=1;
if(b[j] > b[i])cnt2^=1;
}
}
if(cnt1 != cnt2&&!tw)fg = 0;
if(!fg)puts("No");
else puts("Yes");
}
int main()
{
int _=1;
//scanf("%d",&_);
while(_--){
AC();
}
return 0;
}
比赛时只有思路1
思路2还是赛后学习了最短的c++代码想到的
希望以后可以切了arc的B