求助站外题证明
  • 板块学术版
  • 楼主火羽白日生
  • 当前回复24
  • 已保存回复24
  • 发布时间2021/6/11 20:55
  • 上次更新2023/11/4 22:00:35
查看原帖
求助站外题证明
226113
火羽白日生楼主2021/6/11 20:55

rt,yy了一种 O(n)O(n) 的写法,但不知道为何正确,交了一发A了,现在对着 stdstd 拍了 50005000 组数据也没错

假如已经能 O(1)O(1) 求出每个 R 移到区间两端的代价

如何证明对于每一个枚举的区间,取区间中点时所得答案取 min\min 一定是最优的

Code:\texttt{Code:}

#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define rint register int
#define fill(x,y) memset(x,y,sizeof(x))
#define copy(x,y) memcpy(y,x,sizeof(x))

using namespace std;

inline int read(){
	int w=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
	while(ch>='0'&&ch<='9'){w=(w<<3)+(w<<1)+(ch^48); ch=getchar();}
	return w*f;
}

const int maxn=2e6+5;

int T,n,tot; ll ans=0x7fffffffffffffff;
char s[maxn];
ll bl[maxn],br[maxn],sumr[maxn],sl[maxn],sr[maxn];
inline void init(){
	ans=0x7fffffffffffffff; tot=0;
}
inline ll clac(int l,int k,int r){
	return sl[k]-sl[l-1]-bl[l-1]*(sumr[k]-sumr[l-1])+sr[k+1]-sr[r+1]-br[r+1]*(sumr[r]-sumr[k]);
}
int main(){
	T=read();
	while(T--){
		scanf("%s",s+1); n=strlen(s+1);
		for(int i=1;i<=n;i++) s[i+n]=s[i];
		int len=n; n<<=1;
		for(int i=1;i<=n;i++){
			bl[i]=bl[i-1];
			sl[i]=sl[i-1];
			sumr[i]=sumr[i-1];
			if(s[i]=='B') bl[i]++;
			else{
				sumr[i]++;
				sl[i]+=bl[i];
			}
		}
		for(int i=n;i>=1;i--){
			br[i]=br[i+1];
			sr[i]=sr[i+1];
			if(s[i]=='B') br[i]++;
			else sr[i]+=br[i];
		}
		for(int i=1;i<=len;i++){
			int mid=(i+i+len-1)/2;
			ans=min(ans,clac(i,mid,i+len));
		}
		printf("%lld\n",ans);
		init();
	}
	return 0;
}
2021/6/11 20:55
加载中...