A题,模拟
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e2+10;
ll a[N],b[N],t[N];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
ll tt=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%lld%lld",&a[i],&b[i]);
for(int i=1;i<=n;i++)scanf("%lld",&t[i]);
for(int i=1;i<n;i++)
{
tt+=a[i]-b[i-1]+t[i];
tt+=b[i]-a[i]+1>>1;
tt=max(tt,b[i]);
}
cout<<tt+a[n]-b[n-1]+t[n]<<'\n';
}
return 0;
}
B题 差分
第i次操作相当与在b[i+1]-1,在b[i-a[i]+1]+1
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
int a[N],b[N];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
memset(b,0,sizeof b);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
{
b[i+1]--;
b[max(i-a[i]+1,1)]++;
}
for(int i=1;i<=n;i++)
{
b[i]+=b[i-1];
cout<<!!b[i]<<' ';
}
puts("");
}
return 0;
}
C题 (FST了)思维+差分
把原数组排序,求差分数组,若存在b[k]==b[s],即 a [ k ] - a [ k - 1 ] = a [ s ] - a [ s - 1 ]
移项得 a [ k ] + a [ s - 1 ] = a [ s ] + a [ k - 1 ],那么如果k - 1 , k , s - 1 , s 这4个点不重复就满足题意了
下面是我比赛时的代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
struct node{
int num,id;
bool operator<(const node &b)const
{
return num<b.num;
}
}a[N];
int b[N];
unordered_map<int,pair<int,pair<int,int>>>mp;
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i].num);
a[i].id=i;
}
sort(a+1,a+1+n);
for(int i=1;i<=n;i++)b[i]=a[i].num-a[i-1].num;
for(int i=1;i<=n;i++)
{
mp[b[i]].first++;
if(b[i-1]!=b[i]&&mp[b[i]].first>=2)
{
int x1=a[mp[b[i]].second.second-1].id,x2=a[i].id,x3=a[mp[b[i]].second.second].id,x4=a[i-1].id;
if(x1&&x2&&x3&&x4&&x1!=x2&&x1!=x3&&x1!=x4&&x2!=x3&&x2!=x4&&x3!=x4)
{
puts("YES");
cout<<x1<<' '<<x2<<' '<<x3<<' '<<x4;
puts("");
return 0;
}
}
else if(mp[b[i]].first>2)
{
int x1=a[mp[b[i]].second.first-1].id,x2=a[i].id,x3=a[mp[b[i]].second.first].id,x4=a[i-1].id;
if(x1&&x2&&x3&&x4&&x1!=x2&&x1!=x3&&x1!=x4&&x2!=x3&&x2!=x4&&x3!=x4)
{
puts("YES");
cout<<x1<<' '<<x2<<' '<<x3<<' '<<x4;
puts("");
return 0;
}
}
mp[b[i]].second.first=mp[b[i]].second.second;
mp[b[i]].second.second=i;
}
puts("NO");
return 0;
}
后来去看了第一名的代码发现暴力能过,还**挺快的
好像不会找太多次,数分布的密一点的话就能找到
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10,M=2500010;
struct node{
int l,r;
};
vector<node>v[M<<1];
int a[N];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
for(int j=1;j+i<=n;j++)
{
for(auto it:v[a[j]+a[j+i]])
if(it.l!=j+i&&it.l!=j&&it.r!=j&&it.r!=j+i)
{
puts("YES");
cout<<it.l<<' '<<it.r<<' '<<j<<' '<<j+i;
return 0;
}
v[a[j]+a[j+i]].push_back({
j,j+i});
}
puts("NO");
return 0;
}