Educational Codeforces Round 95 (Div. 2) 题解 (ABCD)

A. Buying Torches

大意:初始1木棍,操作1:1木棍换x木棍;操作2:y木棍换1煤炭。1木棍和1煤炭合成1火把,求合成k火把至少操作次数

木棍需要至少 \(k+ky\) 条,每次操作1会多 \(x-1\) 个木棍,初始1木棍,所以操作1进行的次数是 \(\lceil\dfrac{k+ky-1}{x-1}\rceil\),操作2是k次

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
#define mst(a,x) memset(a,x,sizeof(a))
#define fi first
#define se second
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
const int N=200010; typedef long long ll; const int inf=~0u>>2; const ll INF=~0ull>>2; ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;} typedef double lf; const lf pi=acos(-1.0); lf readf(){lf x; if(scanf("%lf",&x)==-1)exit(0); return x;} typedef pair<ll,ll> pii; template<typename T> void operator<<(vector<T> &a,T b){a.push_back(b);}
const ll mod=(1?1000000007:998244353); ll mul(ll a,ll b,ll m=mod){return a*b%m;} ll qpow(ll a,ll b,ll m=mod){ll ans=1; for(;b;a=mul(a,a,m),b>>=1)if(b&1)ans=mul(ans,a,m); return ans;}
#define int ll
void Solve(){
	int x=read(),y=read(),k=read();
	cout<<(k+k*y-1+x-1-1)/(x-1)+k<<endl;
}
signed main(){
	//freopen("data.txt","r",stdin);
	int T=1; T=read();
	repeat(ca,1,T+1){
		Solve();
	}
	return 0;
}

B. Negative Prefixes

大意:给一个序列,可以将某些位置的数字重新排列,令k为这个序列的前缀和的最后k个位置都是正数,的k的最大值。求k最大时重新排列之后的序列

把能排列的这些数字sort一下

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
#define mst(a,x) memset(a,x,sizeof(a))
#define fi first
#define se second
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
const int N=200010; typedef long long ll; const int inf=~0u>>2; const ll INF=~0ull>>2; ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;} typedef double lf; const lf pi=acos(-1.0); lf readf(){lf x; if(scanf("%lf",&x)==-1)exit(0); return x;} typedef pair<ll,ll> pii; template<typename T> void operator<<(vector<T> &a,T b){a.push_back(b);}
const ll mod=(1?1000000007:998244353); ll mul(ll a,ll b,ll m=mod){return a*b%m;} ll qpow(ll a,ll b,ll m=mod){ll ans=1; for(;b;a=mul(a,a,m),b>>=1)if(b&1)ans=mul(ans,a,m); return ans;}
#define int ll
int a[N],l[N];
vector<int> v;
void Solve(){
	int n=read(); v.clear();
	repeat(i,0,n)a[i]=read();
	repeat(i,0,n)l[i]=read();
	repeat(i,0,n)if(!l[i])v<<a[i]; //"<<" means push_back
	sort(v.begin(),v.end());
	repeat(i,0,n)if(!l[i])a[i]=v.back(),v.pop_back();
	repeat(i,0,n)cout<<a[i]<<' ';
	cout<<endl;
}
signed main(){
	//freopen("data.txt","r",stdin);
	int T=1; T=read();
	repeat(ca,1,T+1){
		Solve();
	}
	return 0;
}

C. Mortal Kombat Tower

大意:有n个怪,每个怪要么0要么1。你和你朋友每回合可以杀1个或2个怪,但是只能按给定顺序清怪。两个玩家轮流操作,你朋友先操作。求你朋友杀的1型怪的个数最小值

dp,\(dp[i][j]\) 表示杀前i个怪,j号玩家杀的第i个怪的时候,你朋友杀的1型怪个数的最小值。转移方程见代码

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
#define mst(a,x) memset(a,x,sizeof(a))
#define fi first
#define se second
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
const int N=200010; typedef long long ll; const int inf=~0u>>2; const ll INF=~0ull>>2; ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;} typedef double lf; const lf pi=acos(-1.0); lf readf(){lf x; if(scanf("%lf",&x)==-1)exit(0); return x;} typedef pair<ll,ll> pii; template<typename T> void operator<<(vector<T> &a,T b){a.push_back(b);}
const ll mod=(1?1000000007:998244353); ll mul(ll a,ll b,ll m=mod){return a*b%m;} ll qpow(ll a,ll b,ll m=mod){ll ans=1; for(;b;a=mul(a,a,m),b>>=1)if(b&1)ans=mul(ans,a,m); return ans;}
#define int ll
int Dp[N][2],(*dp)[2]=Dp+1,a[N];
void Solve(){
	int n=read();
	repeat(i,1,n+1)a[i]=read();
	dp[0][0]=dp[-1][0]=inf;
	repeat(i,1,n+1){
		dp[i][0]=min(dp[i-1][1]+a[i],dp[i-2][1]+a[i]+a[i-1]);
		dp[i][1]=min(dp[i-1][0],dp[i-2][0]);
	}
	cout<<min(dp[n][0],dp[n][1])<<endl;
}
signed main(){
	//freopen("data.txt","r",stdin);
	int T=1; T=read();
	repeat(ca,1,T+1){
		Solve();
	}
	return 0;
}

D. Trash Problem

大意:有一些石子放在x轴上。把区间[l,r]的石子合在一起的花费是r-l(和题目不太相同,意思到了就行),动态询问把这些石子合到最多两堆的花费。操作是去掉石子和添加石子

因为答案刚好就是所有石子位置最大值减最小值减相邻石子的最大间隔,维护最大间隔比较麻烦

搞一个set和一个multiset。set表示所有石子的位置,multiset表示所有间隔。添加删除石子时,对set就直接嗯操作就行了,然后得到set里这个位置的前驱后继,multiset的修改量就是这个位置和前驱和后继之间的距离

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
#define mst(a,x) memset(a,x,sizeof(a))
#define fi first
#define se second
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
const int N=200010; typedef long long ll; const int inf=~0u>>2; const ll INF=~0ull>>2; ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;} typedef double lf; const lf pi=acos(-1.0); lf readf(){lf x; if(scanf("%lf",&x)==-1)exit(0); return x;} typedef pair<ll,ll> pii; template<typename T> void operator<<(vector<T> &a,T b){a.push_back(b);}
const ll mod=(1?1000000007:998244353); ll mul(ll a,ll b,ll m=mod){return a*b%m;} ll qpow(ll a,ll b,ll m=mod){ll ans=1; for(;b;a=mul(a,a,m),b>>=1)if(b&1)ans=mul(ans,a,m); return ans;}
#define int ll
set<int> st; multiset<int> st2;
void output(){
	if(st.size()<=3)cout<<0<<endl;
	else cout<<*++st.rbegin()-*++st.begin()-*++++st2.rbegin()<<endl;
}
void Solve(){
	int n=read(),q=read(); st.clear(); st2.clear();
	st.insert(-INF/2); st.insert(INF/2);
	repeat(i,0,n)st.insert(read());
	for(auto i=st.begin();i!=st.end();i++){
		auto j=next(i);
		if(j!=st.end())st2.insert(*j-*i);
	}
	output();
	while(q--){
		int op=read(),x=read();
		if(op==0){
			auto i=st.lower_bound(x);
			st2.erase(st2.lower_bound(*i-*prev(i)));
			st2.erase(st2.lower_bound(*next(i)-*i));
			st2.insert(*next(i)-*prev(i));
			st.erase(i);
		}
		else{
			if(!st.count(x)){
				auto i=st.insert(x).first;
				st2.erase(st2.lower_bound(*next(i)-*prev(i)));
				st2.insert(*i-*prev(i));
				st2.insert(*next(i)-*i);
			}
		}
		output();
	}
}
signed main(){
	//freopen("data.txt","r",stdin);
	int T=1; //T=read();
	repeat(ca,1,T+1){
		Solve();
	}
	return 0;
}
posted @ 2020-09-15 00:34  axiomofchoice  阅读(308)  评论(1编辑  收藏  举报