乱搞做法求 hack
查看原帖
乱搞做法求 hack
661096
asas111楼主2024/12/1 20:45

从小到大开始遍历,在 ii 这个位置如果 si,1si,2s_{i,1}\neq s_{i,2},且 ti,1,ti,2t_{i,1},t_{i,2} 不都为 00,则往后遍历,找到在同一个块里第一个 si=sjs_i=s_j,给它 swap 回去,这个东西是 O(n2)O(n^2) 的,有 60pts

然后我当时想了一个乱搞:对于第二个循环,保存之前跑到过的位置,之后直接从这个位置开始跑,就是 O(n)O(n) 的,然后这个东西过了大样例和随机数据

#include<bits/stdc++.h>
#define il int
#define ll long long
#define lll __int128
#define ull unsigned long long
#define pl pair<ll,ll>
#define vl vector<ll>
#define _for(i,a,b) for(ll i=(a);i<=(b);++i)
#define _forc(i,a,b,c) for(ll i=(a);i<=(b);++i,c)
#define _rep(i,a,b) for(ll i=(a);i>=(b);--i)
#define _repc(i,a,b,c) for(ll i=(a);i>=(b);--i,c)
#define fi first
#define se second
#define pb push_back
#define bg begin()
#define ed end()
using namespace std;
ll read(){ll s=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c))s=s*10+c-'0',c=getchar();return s*f;}
char readc(){char c=getchar();while(!isalnum(c)&&!ispunct(c))c=getchar();return c;}
string reads(){string s="";char c=getchar();while(!isalnum(c)&&!ispunct(c))c=getchar();while(isalnum(c)||ispunct(c))s+=c,c=getchar();return s;}
void write(ll x){if(x<0){putchar('-');x=-x;}if(x>9)write(x/10);putchar(x%10+'0');}
void pc(){putchar(' ');}
void pn(){puts("");}
void cmin(ll&a,ll b){a>b?a=b:0;}
void cmax(ll&a,ll b){a<b?a=b:0;}
#define N 100009
#define INF 1e18
#define mod 998244353
#define eps 1e-7
ll T,n,ans,l1,l2;
string s1,s2,t1,t2;
int main(){
	T=read();
	while(T--){
		n=read(),s1=" "+reads(),s2=" "+reads(),t1=" "+reads(),t2=" "+reads(),ans=l1=l2=0;
		_for(i,1,n){
			if(s1[i]==s2[i]){ans++;continue;}
			else if(t1[i]=='0'&&t2[i]=='0')continue;
			bool c1=0;
			if(t1[i]=='1')
				for(l1=max(l1,i+1);t1[l1]=='1';l1++)
					if(s1[i]!=s1[l1]){
						c1=1,ans++,swap(s1[i],s1[l1]);
						break;
					}
			if(c1)continue;
			if(t2[i]=='1')
				for(l2=max(l2,i+1);t2[l2]=='1';l2++)
					if(s2[i]!=s2[l2]){
						ans++,swap(s2[i],s2[l2]);
						break;
					}
		}
//		cout<<s1<<"\n"<<s2<<"\n";
		write(ans),pn();
	}
	return 0;
}
2024/12/1 20:45
加载中...