Cookies

Cookies

qoj 难度为 \(8\),很牛的题。


首先对题目进行转化,考虑加入初始糖果 \(k\) 后答案的变化。

我们定义一个变量 \(v = a_k\),接下来从 \(1\)\(m\) 依次处理下标 \(i\)

  • \(s_i = \texttt{S}\)\(v > b_i\),则交换 \(v\)\(b_i\)

  • \(s_i = \texttt{B}\)\(v < b_i\),则交换 \(v\)\(b_i\)

显然在这套过程过后,\(v\) 就是新留下来的饼干,我们需要求出 \(v\) 的值。


考虑按照 \(s_i\) 将饼干合成连续段,这里以 \(s_i = \texttt{S}\) 为例。

经过若干个 \(\texttt{S}\) 后,桌上剩余的饼干必然会越来越苦。

考虑将这些 \(\texttt{S}\) 合并成一个小根堆,记堆顶为 \(top\),则:

  • \(v > top\),则交换 \(v\)\(top\)

对于 \(\texttt{B}\),维护一个大根堆:

  • \(v < top\),则交换 \(v\)\(top\)

有如下结论:

  • 若存在相邻的 \(\texttt{SB}\),且 \(top_S \geq top_B\),则可以交换这两者。

分类讨论:

  • \(v > top_S\) 时,只会和小根堆交换,显然结果不变,\(v < top_B\) 同理

  • \(top_B \leq v \leq top_S\) 时,两者都不会交换,结果不变

在交换完后,我们仍然可以与旁边的堆进行合并。

我们声称这么做的复杂度是双 \(\log\) 的,我不会证。

#include<iostream>
#include<cstdio>
#include<queue>
#include<stack>
using namespace std;
const long long mod=1000000000;
const bool S=false,B=true;
long long a[200010],b[200010];
int m[200010];
priority_queue<int,vector<int>,greater<int> > pq_S[200010];
priority_queue<int,vector<int>,less<int> > pq_B[200010];
bool check_id(int id){
	if(!pq_S[id].empty()){
		return S; 
	}
	if(!pq_B[id].empty()){
		return B;
	}
}
stack<int> st;
long long solve(long long v){
	stack<int> add_st;
	while(!st.empty()){
		add_st.push(st.top());
		st.pop();
	}
	while(!add_st.empty()){
		int id_now=add_st.top();
		add_st.pop();
		if(st.empty()){
			st.push(id_now);
		}
		else{
			int id_lst=st.top();
			st.pop();
			bool check_lst=check_id(id_lst),check_now=check_id(id_now);
			if(check_lst==S  &&  check_now==S){
				if(pq_S[id_lst].size()>pq_S[id_now].size()){
					swap(pq_S[id_lst],pq_S[id_now]); 
				}
				while(!pq_S[id_lst].empty()){
					pq_S[id_now].push(pq_S[id_lst].top());
					pq_S[id_lst].pop();
				}
				add_st.push(id_now);
			}
			if(check_lst==S  &&  check_now==B){
				if(pq_S[id_lst].top()>=pq_B[id_now].top()){
					if(st.empty()){
						st.push(id_lst);
						st.push(id_now);
					}
					else{
						add_st.push(id_lst);
						add_st.push(id_now);
					}
				}
				else{
					st.push(id_lst);
					st.push(id_now);
				}
			}
			if(check_lst==B  &&  check_now==S){
				if(pq_B[id_lst].top()<=pq_S[id_now].top()){
					if(st.empty()){
						st.push(id_lst);
						st.push(id_now);
					}
					else{
						add_st.push(id_lst);
						add_st.push(id_now);
					}
				}
				else{
					st.push(id_lst);
					st.push(id_now);
				}
			}
			if(check_lst==B  &&  check_now==B){
				if(pq_B[id_lst].size()>pq_B[id_now].size()){
					swap(pq_B[id_lst],pq_B[id_now]); 
				}
				while(!pq_B[id_lst].empty()){
					pq_B[id_now].push(pq_B[id_lst].top());
					pq_B[id_lst].pop();
				}
				add_st.push(id_now);
			}
		}
	}
	while(!st.empty()){
		add_st.push(st.top());
		st.pop();
	}
	while(!add_st.empty()){
		int id_now=add_st.top();
		add_st.pop();
		bool check_now=check_id(id_now);
		if(check_now==S){
			long long pre=pq_S[id_now].top();
			pq_S[id_now].pop();
			if(v>pre){
				swap(v,pre);
			}
			pq_S[id_now].push(pre);
		}
		if(check_now==B){
			long long pre=pq_B[id_now].top();
			pq_B[id_now].pop();
			if(v<pre){
				swap(v,pre);
			}
			pq_B[id_now].push(pre);
		}
		st.push(id_now);
	}
	return v;
}
int main(){
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
	}
	int m;
	scanf("%d",&m);
	for(int i=1;i<=n;i++){
		scanf("%lld",&b[i]); 
	}
	for(int i=1;i<=m;i++){
		char ch;
		cin>>ch;
		if(ch=='S'){
			pq_S[i].push(b[i]);
		}
		if(ch=='B'){
			pq_B[i].push(b[i]);
		}
		st.push(i);
	}
	long long last_ans=0;
	for(int i=1;i<=n;i++){
		a[i]=(a[i]+last_ans)%mod;
		last_ans+=solve(a[i]);
		printf("%lld ",last_ans);
	}
	return 0;
}
posted @ 2026-06-12 12:00  Oken喵~  阅读(8)  评论(0)    收藏  举报