如果枚举三维会超时,但是暴力做法却很有道理,根据数据范围,容易看出这是个n^2的题目,并且第三个点是一个区间中的答案
因此考虑用st表查询区间最值优化
#include<bits/stdc++.h> using namespace std; const int N=1e5+10; struct node{ int a; int id; }s[N]; int ans[N]; int st[N][30]; bool cmp(node a,node b){ return a.a>b.a; } int calc(int i){ return s[i].a-s[i+1].a; } int Query(int L,int R){ if (L>R) return -1; int d=log(R-L+1)/log(2.0); int a=st[L+(1<<d)-1][d],b=st[R][d]; return calc(a)>calc(b)?a:b; } int main(){ ios::sync_with_stdio(false); int n; int i,j; cin>>n; for(i=1;i<=n;i++){ cin>>s[i].a; s[i].id=i; } sort(s+1,s+1+n,cmp); for (int i=1;i<=n;i++){ st[i][0]=i; for(int j=1;j<=12;j++){ st[i][j]=st[i][j-1]; if (i-(1<<(j-1))>0&&calc(st[i-(1<<(j-1))][j-1])>calc(st[i][j])) st[i][j]=st[i-(1<<(j-1))][j-1]; } } int d1=-1,d2=-1,d3=-1; for(int i=1;i<=n;i++) for(int j=1;i+j<=n;j++){ if(i>2*j||j>2*i) continue; int dd1=i,dd2=i+j,dd3=Query(dd2+max((i+1)/2,(j+1)/2),min(dd2+min(i*2,j*2),n)); int k=dd3-dd2; if(dd3==-1||k<1) continue; if(d1==-1||calc(dd1)>calc(d1)||(calc(dd1)==calc(d1)&&(calc(dd2)>calc(d2)||(calc(dd2)==calc(d2)&&calc(dd3)>calc(d3))))) d1=dd1,d2=dd2,d3=dd3; } for(i=1;i<=d1;i++){ ans[s[i].id]=1; } for(i=d1+1;i<=d2;i++){ ans[s[i].id]=2; } for(i=d2+1;i<=d3;i++) ans[s[i].id]=3; for(i=d3+1;i<=n;i++) ans[s[i].id]=-1; for(i=1;i<=n;i++) cout<<ans[i]<<" "; cout<<endl; return 0; }
CF873E Awards For Contestants(st表)
原文:https://www.cnblogs.com/ctyakwf/p/14082571.html