Educational Codeforces Round 171 (Rated for Div. 2) - Codeforces
Problem - A - Codeforces
几何 构造
没什么好说的,\(45\)度交的时候长度最大
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
void solve()
{
int x,y,k;cin>>x>>y>>k;
if(x>y)
{
cout<<"0 0 "<<y<<' '<<y<<endl;
cout<<"0 "<<y<<' '<<y<<' '<<"0"<<endl;
}
else
{
cout<<"0 0 "<<x<<' '<<x<<endl;
cout<<"0 "<<x<<' '<<x<<' '<<"0"<<endl;
}
}
int main()
{
int t;cin>>t;
while(t--)solve();
}
Problem - B - Codeforces
构造 二分 优先队列
由于给出的数组是递增的,只需要考虑最大的相邻元素差值就好了
偶数的时候答案是固定的
要注意奇数的时候需要提取一个出来,再去求最小的最大值
数据范围很小,直接枚举即可
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
long long a[N];
int n;
void solve()
{
cin>>n;
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
//sort(a+1,a+1+n);
if(n==1)
{
cout<<"1"<<endl;return ;
}
long long f=2e18;
if(n%2==0)
{
priority_queue<long long>heap;
for(int i=1;i<=n-1;i+=2)
{
heap.push(a[i+1]-a[i]);
}
f=heap.top();
}
else
{
for(int k=1;k<=n;k++)
{
priority_queue<long long>heap;
vector<long long>b;
for(int i=1;i<=n;i++)if(i!=k)b.push_back(a[i]);
for(int i=0;i<n-2;i+=2)
{
heap.push(b[i+1]-b[i]);
}
f=min(f,heap.top());
}
}
cout<<f<<endl;
}
int main()
{
int t;cin>>t;
while(t--)solve();
}
Problem - C - Codeforces
数据结构 双端队列 栈 构造
题意是一个人要买\(1-n\)个机器人各一个
给出一个二进制字符串,\(s[i]=1\)的时候可以在这天购买,反之不能在这天购买
且第\(i\)件物品花费\(i\),只有在\(>= i\)天时候才能购买,如果一次买两件或以上可以有一件免费
不能重复购买
显然如果没有优惠答案便是\(n*(n+1)/2\),只需要考虑尽可能多得使花费大的机器人免费
首先,如果\(s[i]=0\),那么这天上架的机器人一定不能免费,因为\(s[n]=1\),后面一定有更贵的机器人可以选择
如果\(s[i]=1\),可以优先和离他最近的比他小的\(0\)组合,使得\(i\)免费
如果\(0\)用完了,那么就去找没有用过的最小的\(s[i]=1\)的\(i\)结合
显然可以用一个双端队列去维护\(s[i]=1\)的天数,再利用一个栈去维护\(s[i]=0\)的天数
#include<bits/stdc++.h>
using namespace std;
const int N=4e5+10;
typedef pair<int,int> pii;
int sa[N],sc[N];
int n;
void solve()
{
cin>>n;
string s;cin>>s;s=' '+s;
int hh=0,tt=0,st=0,ed=0;
long long ans=1LL*n*(n+1)/2;
if(n==1)
{
cout<<ans<<endl;return ;
}
for(int i=1;i<=n;i++)
{
if(s[i]=='1')sa[++tt]=i;
else sc[++ed]=i;
}
if(tt)hh++;if(ed)st++;
while(hh<=tt)
{
int ind=sa[tt];
while(ed&&sc[ed]>ind)ed--;
if(ed)
{
tt--;
ans-=ind;
ed--;
}
else
{
if(hh<tt)
{
hh++;tt--;
ans=ans-ind;
}
else
{
break;
}
}
}
cout<<ans<<endl;
}
int main()
{
int t;cin>>t;
while(t--)solve();
}
Problem - D - Codeforces
数学 前缀和 二分
给出数组\(a\),使\(\sum_{i=l}^{r}a_i=s(l,r)\)
那么构造数组\(b\),\(b=[s(1,1),s(1,2),s(1,3)..s(1,n),...s(2,2)..s(2,n)..]\)
接下来给出\(q\)个查询,求\(\sum_{i=l}^{r}b_i\)
首先肯定要先处理好处理的部分,观察题目发现,像\(s(1,1)-s(1,n)..s(2,2)-s(2,n)\)这样完整的片段的和是可以在\(o(n)\)
内求出来的,记\(pre_r=\sum_{i=1}^{r}a_i\), \(val_i=\sum_{k=i}^{n}s(i,k)\), \(prepre_r=\sum_{i=i}^{r}pre_i\)
所以可以先求出连续段的个数,总共有\(n\)个连续段,每个段的元素个数为\(n-i+1\)
记\(pos_j\),为前\(j\)个连续段的元素总数
显然对于一个查询\(x\),可以先找出满足\(pos_j<=x\)的最大的\(j\),利用二分得出,然后就是求不完整段的和
不完整段的元素个数为\(x-pos_j\),不完整段的数字从\(j+1\)开始,结束于\(x-pos_j+j\)
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
long long pre[N],prepre[N];
long long pos[N],val[N];
int n;
int a[N];
long long solve(long long x)
{
if(x==0)return 0;
long long l=0,r=n;
while(l<r)
{
long long mid=(l+r+1)>>1;
if(pos[mid]<=x)l=mid;
else r=mid-1;
}
long long ans=val[l];
ans=ans+prepre[x-pos[l]+l]-prepre[l]-(x-pos[l])*pre[l];
return ans;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
pre[i]=pre[i-1]+a[i];
prepre[i]=prepre[i-1]+pre[i];
pos[i]=pos[i-1]+n-i+1;
}
for(int i=1;i<=n;i++)
{
val[i]=val[i-1]+prepre[n]-prepre[i-1]-1LL*(n-i+1)*pre[i-1];
}
int q;scanf("%d",&q);
while(q--)
{
long long ll,rr;scanf("%lld%lld",&ll,&rr);
long long ans=solve(rr)-solve(ll-1);
cout<<ans<<endl;
}
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)