이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#ifndef LOCAL
#pragma GCC optimize ("Ofast")
#pragma GCC optimize ("unroll-loops")
#endif
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
#define int ll
#define rng(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,b) rng(i,0,b)
#define gnr(i,a,b) for(int i=int(b)-1;i>=int(a);i--)
#define per(i,b) gnr(i,0,b)
#define pb push_back
#define eb emplace_back
#define a first
#define b second
#define bg begin()
#define ed end()
#define all(x) x.bg,x.ed
#define si(x) int(x.size())
#ifdef LOCAL
#define dmp(x) cerr<<__LINE__<<" "<<#x<<" "<<x<<endl
#else
#define dmp(x) void(0)
#endif
template<class t,class u> bool chmax(t&a,u b){if(a<b){a=b;return true;}else return false;}
template<class t,class u> bool chmin(t&a,u b){if(b<a){a=b;return true;}else return false;}
template<class t> using vc=vector<t>;
template<class t> using vvc=vc<vc<t>>;
using pi=pair<int,int>;
using vi=vc<int>;
template<class t,class u>
ostream& operator<<(ostream& os,const pair<t,u>& p){
	return os<<"{"<<p.a<<","<<p.b<<"}";
}
template<class t> ostream& operator<<(ostream& os,const vc<t>& v){
	os<<"{";
	for(auto e:v)os<<e<<",";
	return os<<"}";
}
#define mp make_pair
#define mt make_tuple
#define one(x) memset(x,-1,sizeof(x))
#define zero(x) memset(x,0,sizeof(x))
#ifdef LOCAL
void dmpr(ostream&os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
	os<<t<<" ";
	dmpr(os,args...);
}
#define dmp2(...) dmpr(cerr,__LINE__,##__VA_ARGS__)
#else
#define dmp2(...) void(0)
#endif
using uint=unsigned;
using ull=unsigned long long;
template<class t,size_t n>
ostream& operator<<(ostream&os,const array<t,n>&a){
	return os<<vc<t>(all(a));
}
template<int i,class T>
void print_tuple(ostream&,const T&){
}
template<int i,class T,class H,class ...Args>
void print_tuple(ostream&os,const T&t){
	if(i)os<<",";
	os<<get<i>(t);
	print_tuple<i+1,T,Args...>(os,t);
}
template<class ...Args>
ostream& operator<<(ostream&os,const tuple<Args...>&t){
	os<<"{";
	print_tuple<0,tuple<Args...>,Args...>(os,t);
	return os<<"}";
}
template<class t>
void print(t x,int suc=1){
	cout<<x;
	if(suc==1)
		cout<<"\n";
	if(suc==2)
		cout<<" ";
}
ll read(){
	ll i;
	cin>>i;
	return i;
}
vi readvi(int n,int off=0){
	vi v(n);
	rep(i,n)v[i]=read()+off;
	return v;
}
pi readpi(int off=0){
	int a,b;cin>>a>>b;
	return pi(a+off,b+off);
}
template<class t,class u>
void print(const pair<t,u>&p,int suc=1){
	print(p.a,2);
	print(p.b,suc);
}
template<class t,class u>
void print_offset(const pair<t,u>&p,ll off,int suc=1){
	print(p.a+off,2);
	print(p.b+off,suc);
}
template<class T>
void print(const vector<T>&v,int suc=1){
	rep(i,v.size())
		print(v[i],i==int(v.size())-1?suc:2);
}
template<class T>
void print_offset(const vector<T>&v,ll off,int suc=1){
	rep(i,v.size())
		print(v[i]+off,i==int(v.size())-1?suc:2);
}
template<class T,size_t N>
void print(const array<T,N>&v,int suc=1){
	rep(i,N)
		print(v[i],i==int(N)-1?suc:2);
}
string readString(){
	string s;
	cin>>s;
	return s;
}
template<class T>
T sq(const T& t){
	return t*t;
}
void YES(bool ex=true){
	cout<<"YES\n";
	if(ex)exit(0);
	#ifdef LOCAL
	cout.flush();
	#endif
}
void NO(bool ex=true){
	cout<<"NO\n";
	if(ex)exit(0);
	#ifdef LOCAL
	cout.flush();
	#endif
}
void Yes(bool ex=true){
	cout<<"Yes\n";
	if(ex)exit(0);
	#ifdef LOCAL
	cout.flush();
	#endif
}
void No(bool ex=true){
	cout<<"No\n";
	if(ex)exit(0);
	#ifdef LOCAL
	cout.flush();
	#endif
}
//#define CAPITAL
/*
void yes(bool ex=true){
	#ifdef CAPITAL
	cout<<"YES"<<"\n";
	#else
	cout<<"Yes"<<"\n";
	#endif
	if(ex)exit(0);
	#ifdef LOCAL
	cout.flush();
	#endif
}
void no(bool ex=true){
	#ifdef CAPITAL
	cout<<"NO"<<"\n";
	#else
	cout<<"No"<<"\n";
	#endif
	if(ex)exit(0);
	#ifdef LOCAL
	cout.flush();
	#endif
}*/
void possible(bool ex=true){
	#ifdef CAPITAL
	cout<<"POSSIBLE"<<"\n";
	#else
	cout<<"Possible"<<"\n";
	#endif
	if(ex)exit(0);
	#ifdef LOCAL
	cout.flush();
	#endif
}
void impossible(bool ex=true){
	#ifdef CAPITAL
	cout<<"IMPOSSIBLE"<<"\n";
	#else
	cout<<"Impossible"<<"\n";
	#endif
	if(ex)exit(0);
	#ifdef LOCAL
	cout.flush();
	#endif
}
constexpr ll ten(int n){
	return n==0?1:ten(n-1)*10;
}
const ll infLL=LLONG_MAX/3;
#ifdef int
const int inf=infLL;
#else
const int inf=INT_MAX/2-100;
#endif
int topbit(signed t){
	return t==0?-1:31-__builtin_clz(t);
}
int topbit(ll t){
	return t==0?-1:63-__builtin_clzll(t);
}
int topbit(ull t){
	return t==0?-1:63-__builtin_clzll(t);
}
int botbit(signed a){
	return a==0?32:__builtin_ctz(a);
}
int botbit(ll a){
	return a==0?64:__builtin_ctzll(a);
}
int botbit(ull a){
	return a==0?64:__builtin_ctzll(a);
}
int popcount(signed t){
	return __builtin_popcount(t);
}
int popcount(ll t){
	return __builtin_popcountll(t);
}
int popcount(ull t){
	return __builtin_popcountll(t);
}
bool ispow2(int i){
	return i&&(i&-i)==i;
}
ll mask(int i){
	return (ll(1)<<i)-1;
}
ull umask(int i){
	return (ull(1)<<i)-1;
}
ll minp2(ll n){
	if(n<=1)return 1;
	else return ll(1)<<(topbit(n-1)+1);
}
bool inc(int a,int b,int c){
	return a<=b&&b<=c;
}
template<class t> void mkuni(vc<t>&v){
	sort(all(v));
	v.erase(unique(all(v)),v.ed);
}
ll rand_int(ll l, ll r) { //[l, r]
	//#ifdef LOCAL
	static mt19937_64 gen;
	/*#else
	static mt19937_64 gen(chrono::steady_clock::now().time_since_epoch().count());
	#endif*/
	return uniform_int_distribution<ll>(l, r)(gen);
}
ll rand_int(ll k){ //[0,k)
	return rand_int(0,k-1);
}
template<class t>
void myshuffle(vc<t>&a){
	rep(i,si(a))swap(a[i],a[rand_int(0,i)]);
}
template<class t>
int lwb(const vc<t>&v,const t&a){
	return lower_bound(all(v),a)-v.bg;
}
template<class t>
bool bis(const vc<t>&v,const t&a){
	return binary_search(all(v),a);
}
vvc<int> readGraph(int n,int m){
	vvc<int> g(n);
	rep(i,m){
		int a,b;
		cin>>a>>b;
		//sc.read(a,b);
		a--;b--;
		g[a].pb(b);
		g[b].pb(a);
	}
	return g;
}
vvc<int> readTree(int n){
	return readGraph(n,n-1);
}
vc<ll> presum(const vi&a){
	vc<ll> s(si(a)+1);
	rep(i,si(a))s[i+1]=s[i]+a[i];
	return s;
}
//BIT ã§æ•°åˆ—を管ç†ã™ã‚‹ã¨ãã«ä½¿ã† (CF850C)
template<class t>
vc<t> predif(vc<t> a){
	gnr(i,1,si(a))a[i]-=a[i-1];
	return a;
}
template<class t>
void transvvc(int&n,int&m,vvc<t>&a){
	assert(si(a)==n);
	vvc<int> b(m,vi(n));
	rep(i,n){
		assert(si(a[i])==m);
		rep(j,m)b[j][i]=a[i][j];
	}
	a.swap(b);
	swap(n,m);
}
//ソートã—㦠i 番目㌠idx[i]
//CF850C
template<class t>
vi sortidx(const vc<t>&a){
	int n=si(a);
	vi idx(n);iota(all(idx),0);
	sort(all(idx),[&](int i,int j){return a[i]<a[j];});
	return idx;
}
//vs[i]=a[idx[i]]
//例ãˆã° sortidx ã§å¾—㟠idx を使ãˆã°å˜ã«ã‚½ãƒ¼ãƒˆåˆ—ã«ãªã£ã¦è¿”ã£ã¦ãã‚‹
//CF850C
template<class t>
vc<t> a_idx(const vc<t>&a,const vi&idx){
	int n=si(a);
	assert(si(idx)==n);
	vc<t> vs(n);
	rep(i,n)vs[i]=a[idx[i]];
	return vs;
}
//CF850C
vi invperm(const vi&p){
	int n=si(p);
	vi q(n);
	rep(i,n)q[p[i]]=i;
	return q;
}
template<class t,class s=t>
s SUM(const vc<t>&a){
	return accumulate(all(a),s(0));
}
//使ã£ãŸã‚¹ãƒ†ãƒƒãƒ—æ•°ã®æƒ…å ±ã‚’æŒã¤ convex hull
//F(a,b)=true ãªã‚‰ a を優先
//min-hull ãªã‚‰ less ã‚’ã„れれã°ã„ã„
//eval ã®å€¤ãŒ 10^18 オーダーãªã‚‰ã ã„ãŸã„ã†ã¾ã行ãよã†ã«ãªã£ã¦ã„ã‚‹ã¯ãš
//stress-tested (CC 2023-2 Cookoff G)
struct linelr{
	int a,b,c,d;
	int eval(int x){
		return a*x+b;
	}
};
ostream&operator<<(ostream&os,const linelr&ln){
	return os<<"L{"<<ln.a<<","<<ln.b<<","<<ln.c<<","<<ln.d<<"}";
}
template<class F>
struct vlr{
	int v=F()(inf,-inf)?-inf:inf,l=-inf,r=inf;
	static vlr merge(const vlr&a,const vlr&b){
		if(F()(a.v,b.v))return a;
		else if(F()(b.v,a.v))return b;
		else return {a.v,min(a.l,b.l),max(a.r,b.r)};
	}
	bool operator==(const vlr&rhs)const{
		return v==rhs.v&&l==rhs.l&&r==rhs.r;
	}
	bool operator!=(const vlr&rhs)const{
		return v!=rhs.v||l!=rhs.l||r!=rhs.r;
	}
	vlr operator+(int a)const{
		return {v+a,l,r};
	}
	void adv(int a){
		v+=a;
		l++;
		r++;
	}
};
template<class F>
ostream&operator<<(ostream&os,const vlr<F>&z){
	return os<<"vlr{"<<z.v<<",["<<z.l<<","<<z.r<<"]}";
}
template<class F>
struct chtlr{
	static int fdiv(int a,int b){
		return a / b - ((a ^ b) < 0 && a % b);
	}
	static int cdiv(int a,int b){
		return a / b + ((a ^ b) > 0 && a % b);
	}
	//can b be the opt?
	static bool cmpline(const linelr&a,const linelr&b,const linelr&c){
		int ay=a.b-b.b,ax=b.a-a.a;
		int by=b.b-c.b,bx=c.a-b.a;
		return cdiv(ay,ax)<=fdiv(by,bx);
	}
	vector<linelr> ls;
	int head,prex;
	vlr<F> preres;
	chtlr(){clear();}
	void clear(){
		ls.clear();
		head=0;
		prex=-inf;
		preres=vlr<F>();
	}
	//min-hull -> z.a is non-increasing
	void add(linelr z){
		if(si(ls))assert(!F()(ls.back().a,z.a));
		if(prex!=-inf)preres=vlr<F>::merge(preres,{z.eval(prex),z.c,z.d});
		if(si(ls)&&ls.back().a==z.a){
			auto&w=ls.back();
			if(F()(w.b,z.b)){
				return;
			}else if(F()(z.b,w.b)){
				ls.pop_back();
			}else{
				chmin(w.c,z.c);
				chmax(w.d,z.d);
				return;
			}
		}
		while(si(ls)>=2){
			int s=si(ls);
			if(cmpline(ls[s-2],ls[s-1],z))
				break;
			ls.pop_back();
		}
		chmin(head,si(ls));
		ls.push_back(z);
	}
	void add(int a,int b,int c,int d){add(linelr{a,b,c,d});}
	//x is non-decreasing
	vlr<F> query(int x){
		if(ls.empty())return vlr<F>();
		assert(prex<=x);
		if(prex==x)return preres;
		while(head+1<si(ls)){
			if(F()(ls[head+1].eval(x),ls[head].eval(x))) head++;
			else break;
		}
		int res=ls[head].eval(x),c=ls[head].c,d=ls[head].d;
		while(head+1<si(ls)&&!F()(res,ls[head+1].eval(x))){
			head++;
			chmin(c,ls[head].c);
			chmax(d,ls[head].d);
		}
		prex=x;
		return preres={res,c,d};
	}
};
//monge コストã§ã¡ã‚‡ã†ã© k step ã§ã‚„れ,ã¿ãŸã„ãªæœ€å°åŒ–å•題 
//max(f(x))-max(f(x)) ã®ä¸Šç•Œã‚’ dif ã§ä¸Žãˆã¦ã„ã‚‹
template<class F>
int kstepmin(int k,int dif,F f){
	assert(dif>=0);
	int lw=-1;
	int up=dif+1;
	while(up-lw>1){
		int mid=(lw+up)/2;
		auto z=f(mid);
		if(z.r<k){
			up=mid;
		}else if(k<z.l){
			lw=mid;
		}else return z.v-mid*k;
	}
	dmp2(lw,up);
	assert(false);
}
//stress-tested
template<class N>
struct slide_monoid{
	vc<N> a,b;
	int head,mid;
	slide_monoid(){clear();}
	void clear(){
		a.clear();
		b.clear();b.eb();
		head=0;
		mid=0;
	}
	void push(const N&x){
		a.pb(x);
		b.pb(N::merge(b.back(),x));
	}
	void pop(){
		if(++head>mid){
			b.back()=N();
			mid=si(b)-1;
			gnr(i,head,mid)
				b[i]=N::merge(a[i],b[i+1]);
		}
		assert(head<=mid);
	}
	N get(){
		return N::merge(b[head],b.back());
	}
};
int slv(int n,int k,string s){
	int off=0;
	vi a;
	{
		int x=0,y=0;
		rep(i,2*n){
			if(s[i]=='A'){
				int v=min(x,y);
				off+=y-v;
				a.pb(v);
				x++;
			}else{
				y++;
			}
		}
	}
	vi b=presum(a);
	using V=vlr<less<int>>;
	chtlr<less<int>> cht;
	slide_monoid<V> sm;
	vc<V> dp(n+1);
	auto f=[&](int cost)->V{
		cht.clear();
		sm.clear();
		int j=0;
		rep(i,n+1){
			if(i==0){
				dp[i]={0,0,0};
			}else{
				dp[i]=V::merge(cht.query(i)+b[i],sm.get());
				dp[i].adv(cost);
			}
			sm.push(dp[i]);
			if(i<n){
				while(j<a[i]){
					sm.pop();
					cht.add(-j,dp[j].v-b[i]+j*i,dp[j].l,dp[j].r);
					j++;
				}
			}
		}
		return dp[n];
	};
	return kstepmin(k,n*n,f)+off;
}
signed main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cout<<fixed<<setprecision(20);
	
	int n,k;cin>>n>>k;
	string s;cin>>s;
	print(slv(n,k,s));
}
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |