CF1697C awoo's Favorite Problem

https://www.luogu.com.cn/problem/CF1697C

船新做法。

考虑 \(ab \to ba\)\(bc\to cb\) 都可以看成邻位交换。

即记 \(a=1,b=2,c=3\),能交换 \(i,i+1\) 当且仅当 \(v_i+1=v_{i+1}\)

然后交换的过程就是冒泡排序,但因为我们只需要判断是否可行。

所以我们可以按在 \(b\) 中的相对顺序对 \(a\) 进行重编号,那么就转为要让 \(a\) 按从小到大排列,每次可以交换相邻 2 个数(满足上述规则)

考虑 2 个数会邻位交换当且仅当 \(i<j,nex_i>nex_j\)\(nex\) 为交换后的编号。

然后就限制一下加个树状数组就好了。

#include <bits/stdc++.h>
#define int long long
#define pb push_back
using namespace std;
const int N=(int)(1e5+5); 
struct node {
	int x,fl;
}v[N];
int n,p1[N],p2[N],p3[N],tot1,tot2,tot3;
char a[N],b[N];

struct BIT {
	#define lowbit(x) (x&(-x))
	int sum[N];	
	void upt(int x,int v) {
		while(x<=n) sum[x]+=v,x+=lowbit(x);
	}
	int qry(int x) {
		int res=0;
		while(x) res+=sum[x],x-=lowbit(x);
		return res;
	}
}T1,T2,T3,Tall;

void solve() {
	cin>>n>>a+1>>b+1; tot1=tot2=tot3=0;
	int cnta=0,cntb=0,cntc=0;
	for(int i=1;i<=n;i++) {
		if(a[i]=='a') ++cnta;
		else if(a[i]=='b') ++cntb;
		else ++cntc;
	}
	for(int i=1;i<=n;i++) {
		if(b[i]=='a') --cnta;
		else if(b[i]=='b') --cntb;
		else --cntc;
	}
	if(cnta!=0||cntb!=0||cntc!=0) {
		cout<<"NO\n"; return ;
	}
	for(int i=1;i<=n;i++) {
		if(b[i]=='a') p1[++tot1]=i;
		else if(b[i]=='b') p2[++tot2]=i;
		else p3[++tot3]=i;
	}
	int t1=0,t2=0,t3=0;
	for(int i=1;i<=n;i++) {
		if(a[i]=='a') ++t1,v[i].x=p1[t1],v[i].fl=1;
		else if(a[i]=='b') ++t2,v[i].x=p2[t2],v[i].fl=2;
		else ++t3,v[i].x=p3[t3],v[i].fl=3;
	}
	bool ans=1;
	for(int i=1;i<=n;i++) {
//		for(int j=1;j<i;j++) {
//			if(v[j].x>v[i].x) {
//				if(v[j].fl+1!=v[i].fl) {
//					ans=0; break ;
//				}
//			}
//		}
		int qwq=Tall.qry(n)-Tall.qry(v[i].x);
		if(v[i].fl==1) {
			if(qwq) ans=0;
			T1.upt(v[i].x,1);
		} else if(v[i].fl==2) {
			int qaq=T1.qry(n)-T1.qry(v[i].x);
			if(qaq!=qwq) ans=0;
			T2.upt(v[i].x,1);
		} else {
			int qaq=T2.qry(n)-T2.qry(v[i].x);
			if(qaq!=qwq) ans=0;
			T3.upt(v[i].x,1);
		}
		Tall.upt(v[i].x,1);
	}
	for(int i=0;i<=n;i++) T1.sum[i]=T2.sum[i]=T3.sum[i]=Tall.sum[i]=0;
	if(ans) cout<<"YES\n"; 
	else cout<<"NO\n";
}

signed main() {
	cin.tie(0); ios::sync_with_stdio(false);
	int T; cin>>T; while(T--) solve();
}
posted @ 2022-08-04 22:04  FxorG  阅读(76)  评论(0)    收藏  举报