求 hack
查看原帖
求 hack
416975
sbno333楼主2024/6/17 18:32

rt,贪心爆改,树状数组加二分寻找最近的有色格子,然后根据中间空格子中小 R 的数量进行决策,赛时满分,但我不知道怎么解释正确性,所以希望 hack。

#include<bits/stdc++.h>
#define int long long
#define mod 998244353
using namespace std;
int s[1000009];
struct st{
	int x;
	bool s;
}q[1000009];
bool cmp(st a1,st a2){
	return a1.x<a2.x;
}
struct stt{
	int f[1000009];
	int lowbit(int x){
		return x&(-x);
	}
	void push(int x){
		while(x<=1000000){
			f[x]++;
			x+=lowbit(x); 
		}
	}
	int q(int x){
		int ans;
		ans=0;
		while(x){
			ans+=f[x];
			x-=lowbit(x); 
		}
		return ans;
	}
	int que(int l,int r){
		return q(r)-q(l-1);
	}
}c;
int ss[1000009];
signed main(){
	int n,m;
	cin>>n>>m;
	s[0]=2;
	s[n+1]=2;
	for(int i=1;i<=n;i++){
		char t;
		cin>>t;
		if(t=='_'){
			s[i]=2;
		}else if(t=='B'){
			s[i]=0;
		}else{
			s[i]=1;
		}
		if(t!='_'){
			c.push(i);
		}
	}
	for(int i=1;i<=m;i++){
		char t;
		cin>>t;
		if(t=='R'){
			q[i].s=1;
		}else{
			q[i].s=0;
		}
		cin>>q[i].x;
		ss[q[i].x]=q[i].s;
	}
	for(int i=1;i<=n;i++){
		ss[i]+=ss[i-1];
	}
	for(int i=1;i<=m;i++){
		if(n==m&&i==1){
			c.push(q[i].x);
			s[q[i].x]=0;
		}else{
			int l,r;
			l=1,r=n;
			while(l<r){
				int mid;
				mid=l+r;
				mid>>=1;
				int s1,s2;
				s1=q[i].x-mid;
				s2=q[i].x+mid;
				s1=max(s1,1ll);
				s2=min(s2,n);
				if(c.que(s1,s2)){
					r=mid;
				}else{
					l=mid+1;
				}
			}
			int s1,s2;
				s1=q[i].x-l;
				s2=q[i].x+l;
				s1=max(s1,1ll);
				s2=min(s2,n);
				if(c.que(s1,q[i].x)){
					if((ss[q[i].x]-ss[s1])&1){
						s[q[i].x]=1-s[s1];
					}else{
						s[q[i].x]=s[s1];
					}
				}else{
					
					if((ss[s2-1]-ss[q[i].x-1])&1){
						s[q[i].x]=1-s[s2];
					}else{
						s[q[i].x]=s[s2];
					}
				}
				c.push(q[i].x);
		}
	}
	int ans;
	ans=0;
	for(int i=1;i<=n;i++){
		if(s[i]!=s[i-1]){
			ans++;
		}
	}
	cout<<ans;
	return 0;
} 
2024/6/17 18:32
加载中...