Codeforces Round 894 (Div. 3)

Dashboard - Codeforces Round 894 (Div. 3) - Codeforces


F

题意是每秒分别产生w和f的两种魔法,然后有n个怪物,打败第i个怪物需要耗费a[i]的w魔法或者是f魔法(不能混用),然后能打败所有怪物的最小时间

我是01背包+二分。也有直接DP的

二分的思路很简单,直接枚举t,然后去验证t秒能不能打败所有怪物即可。

验证方式就是01背包组一个最大的怪物a[i]和,看看sum-最大的和另一种魔法量的关系。

注意一些优化,防止hack tle

事实上寄了。直接DP吧,01背包

查看代码
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<iostream>
#include<algorithm>
#include<cstring>
#include<bitset>
#define ll int
using namespace std;
ll w,f,n,sum;
ll a[105];
inline void solve()
{
	cin>>w>>f>>n;
	sum=0;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		sum+=a[i];
	}
	bitset<1000001>dp;
	dp[0]=1;
	for(int i=1;i<=n;i++)
	{
		for(int j=sum;j>=a[i];j--)
			dp[j]=dp[j]|dp[j-a[i]];
	}
	ll ans=sum;
	for(int i=sum;i>=0;i--)
		if(dp[i])
			ans=min(ans,max((i+w-1)/w,(sum-i+f-1)/f));
	cout<<ans<<"\n";
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t;
	cin>>t;
	while(t--)solve();
	return 0;
}

 


Problem - 1862G - Codeforces

 题意是给一个数组,不断进行以下操作,排序去重,第一个元素+n,第二个+n-1.....第n个+1,然后重复操作,直到只剩一个元素,输出元素。

问题是先给一个数组a,然后有q次询问,每次询问给一个x,y,要求把a[x]=y,然后问此时的最后一个元素是多少。

当时没想出来,赛后看到pyy大佬的题解。思维很清晰

我们考虑第二个操作,对于数组中有序的相邻的两个数x,y来说,假设第一个增长k,那么第二个增长k-1,换言之,x<y在操作后变成了x+k和y+k-1,两者相对来看是差距缩小1,那么操作|y-x|次后,x就会被去重。所以,每次操作都是将相邻两个数的差距-1.最后剩下的两个一定是一开始相邻差距最大的。小的数一定是在操作|y-x|次后才能等于大的数,递推一下,最后剩下的那个就是原数组最大的元素。如果不放心可以反证下,我这里就不赘述了。

然后用两个multiset分别维护原数组和相邻两个数差即可。

当改变某元素的值时,就像链表删点后重新添加那样即可

查看代码
 #pragma GCC optimize(2)
#include<iostream>
#include<set>
#include<iterator>
#include<vector>
using namespace std;
typedef int ll;
ll n,c[200005];
void solve()
{
	cin>>n;
	multiset<ll>a,b;
	auto add=[&](ll x)
	{
		auto it=a.insert(x);
		auto lt=it, nt=it;
		lt--,nt++;
		if(it!=a.begin())
			b.insert(x-*lt);
		if(nt!=a.end())
			b.insert(*nt-x);
		if(it!=a.begin()&&nt!=a.end())
			b.erase(b.find(*nt-*lt));

	};
	auto del=[&](ll x)
	{
		auto it=a.find(x);
		auto lt=it,nt=it;
		--lt,nt++;
		if(it!=a.begin())
			b.erase(b.find(x-*lt));
		if(nt!=a.end())
			b.erase(b.find(*nt-x));
		if(it!=a.begin()&&nt!=a.end())
			b.insert(*nt-*lt);
		a.erase(it);
	};
	for(int i=1;i<=n;i++)
	{
		cin>>c[i];
		add(c[i]);
	}
	int q;
	cin>>q;
	while(q--)
	{
		ll x,y;
		cin>>x>>y;
		del(c[x]);
		add(y);
		c[x]=y;
		if(n==1)
		{
			cout<<c[1]<<' ';
		}
		else 
		cout<<*a.rbegin()+*b.rbegin()<<" ";
	}
	cout<<"\n";
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t;
	cin>>t;
	while(t--)
		solve();
	return 0;
}

 


另外想请教下G++20wa,但17AC的问题的原因

看了看是这个数据

3
731116495414384383
442945409045002977
269115312990797389

C++20输出的答案是C++17输出答案的1/2 


好了,把sqrt改成sqrtl就解决了!

posted @ 2023-08-25 12:00  qbning  阅读(118)  评论(0)    收藏  举报
描述