Codeforces Round 894 (Div. 3)
Dashboard - Codeforces Round 894 (Div. 3) - Codeforces
题意是每秒分别产生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;
}
题意是给一个数组,不断进行以下操作,排序去重,第一个元素+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就解决了!
-------------------------------------------
个性签名:曾经的我们空有一颗望海的心,却从没为前往大海做过真正的努力
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!

浙公网安备 33010602011771号