专栏文章
题解:CF2156E Best Time to Buy and Sell Stock
CF2156E题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @min5mpj7
- 此快照首次捕获于
- 2025/12/01 20:57 3 个月前
- 此快照最后确认于
- 2025/12/01 20:57 3 个月前
我真是太菜了……
First
首先看到是博弈,然后很容易想到这道题是个 Ad-hoc。仔细观察,显然答案具有单调性,设亚历克斯要拼命将美化值调到 ,浩要拼命将美化值弄到 ,假设亚历克斯先走,那么什么情况浩会输?又什么情况浩会赢呢?其实显然,就是设 表示 在 数组中有多少个 ,满足 。那么稍微思考即可得出如果 ,这样亚历克斯第一步禁锢了 之后,反正 有两个匹配 和 ,不管浩删掉哪个亚历克斯都可以选择另一个来使得美化值 ,也就是浩输了,否则的话,那么浩就赢了。
Second
Detail
当然了,这里我们 显然需要 虽然非人哉出题人让非 ,话说出题人你太有生活了),然后没必要知道值,直接看前三小记录,然后大小就是值,并且可以同时找出这个点对应哪些点满足,这里顺便维护前三小是 稍微有亿点难写,本人调了很久结果初值忘了加 ,我真的很有生活了)。
vector(vector 的神奇玩意也水过了set 比较方便,但是由于 set 有 STL 自带常数并且复杂度不算常数也是单次操作 的,这样会使复杂度变成 ,不是最优解法。发现维护前三小可以用变量单次 维护(只不过solution 1
set 的 写法:#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
int a[N];
vector<int>ss[N];
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int _;
cin >> _;
while(_--)
{
int n,maxx = 0;
cin >> n;
for(int i = 1;i<=n;++i)
{
cin >> a[i];
maxx = max(maxx,a[i]);
}
int l = -maxx,r = maxx,ans = 0;
while(l<=r)
{
int mid = l+r>>1;
for(int i = 1;i<=n;++i)
{
ss[i].clear();
}
set<pair<int,int>>s;
for(int i = 1;i<=n;++i)
{
for(auto [x,y]:s)
{
if(a[i]-x>=mid)
{
ss[i].push_back(y);
ss[y].push_back(i);
}
}
s.insert({a[i],i});
if(s.size()>3)
{
s.erase(prev(s.end()));
}
}
int w = 0;
for(int i = 1;i<=n;++i)
{
w+=(ss[i].size()>=2);
}
int flag = 1;
for(int i = 1;i<=n;++i)
{
int si = ss[i].size();
int b = (si>=2);
for(int c:ss[i])
{
b+=(ss[c].size() == 2);
}
if(b == w)
{
flag = 0;
break;
}
}
if(flag)
{
ans = mid;
l = mid+1;
}
else
{
r = mid-1;
}
}
cout << ans << '\n';
}
return 0;
}
solution 2
变量维护写法,:
CPP#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
int a[N];
vector<int>ss[N];
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int _;
cin >> _;
while(_--)
{
int n,maxx = 0;
cin >> n;
for(int i = 1;i<=n;++i)
{
cin >> a[i];
maxx = max(maxx,a[i]);
}
int l = -maxx,r = maxx,ans = 0;
while(l<=r)
{
int mid = l+r>>1;
for(int i = 1;i<=n;++i)
{
ss[i].clear();
}
int minn = maxx+1,minnx = 0,cmin = maxx+1,cminn = 0,tmin = maxx+1,tminn = 0;
for(int i = 1;i<=n;++i)
{
if(a[i]-minn>=mid&&minnx)
{
ss[i].push_back(minnx);
ss[minnx].push_back(i);
}
if(a[i]-cmin>=mid&&cminn)
{
ss[i].push_back(cminn);
ss[cminn].push_back(i);
}
if(a[i]-tmin>=mid&&tminn)
{
ss[i].push_back(tminn);
ss[tminn].push_back(i);
}
if(tmin>a[i])
{
tmin = a[i];
tminn = i;
}
if(cmin>tmin)
{
cmin^=tmin^=cmin^=tmin;
cminn^=tminn^=cminn^=tminn;
}
if(minn>cmin)
{
minn^=cmin^=minn^=cmin;
minnx^=cminn^=minnx^=cminn;
}
}
int w = 0;
for(int i = 1;i<=n;++i)
{
w+=(ss[i].size()>=2);
}
int flag = 1;
for(int i = 1;i<=n;++i)
{
int si = ss[i].size();
int b = (si>=2);
for(int c:ss[i])
{
b+=(ss[c].size() == 2);
}
if(b == w)
{
flag = 0;
break;
}
}
if(flag)
{
ans = mid;
l = mid+1;
}
else
{
r = mid-1;
}
}
cout << ans << '\n';
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...