题解 - C F 1185 D E x t r a E l e m e n t \mathrm{CF1185D\ Extra\ Element} CF1185D Extra Element
题目意思
-
给你一个长为 n n n的序列 a a a,问你能否删除一个数后对数列重拍形成等差数列。如果能输出删除的位置。否则输出 − 1 \mathrm{-1} −1
-
n ≤ 2 e 5 n\leq 2e5 n≤2e5
S o l \mathrm{Sol} Sol
-
小清新贪心题
-
我们首先对原序列重排「就是排序」。然后我们思考如何会构成一个等差数列:打个比方,如果 a = 2 , 4 , 6 , 7 , 8 a={2,4,6,7,8} a=2,4,6,7,8我们删除第 4 4 4个数,那么它与相邻的差合并起来形成新的一个差值 x x x。我们只要判断 x x x是否为序列公差即可。
-
对于这个操作我们 O ( n ) O(n) O(n)枚举去掉那个数。就是假装先删掉这个数然后判断一下再把值改回来,如果合法直接输出就好了。
-
时间复杂度 O ( n log m x ) O(n \log\ mx) O(nlog mx),因为要开个 M A P MAP MAP记录差值所以代只 log \log log
C o d e \mathrm{Code} Code
#include <bits/stdc++.h>
#define For(i,a,b) for ( int i=(a);i<=(b);i++ )
#define Dow(i,b,a) for ( int i=(b);i>=(a);i-- )
#define GO(i,x) for ( int i=head[x];i;i=e[i].nex )
#define mem(x,s) memset(x,s,sizeof(x))
#define cpy(x,s) memcpy(x,s,sizeof(x))
#define YES return puts("YES"),0
#define NO return puts("NO"),0
#define GG return puts("-1"),0
#define pb push_back
#define int long long
using namespace std;
inline int read()
{
int sum=0,ff=1; char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') ff=-1;
ch=getchar();
}
while(isdigit(ch))
sum=sum*10+(ch^48),ch=getchar();
return sum*ff;
}
const int mod=1e9+7;
const int mo=998244353;
const int N=2e5+5;
int n,m,sum[N],b[N],flg,gs;
map<int,int> lyx,wyy;
struct Node
{
int x,id;
inline bool friend operator < (const Node&a,const Node&b)
{
return a.x<b.x;
}
};
Node a[N];
signed main()
{
n=read();
For(i,1,n) a[i]=(Node){read(),i};
sort(a+1,a+n+1);
For(i,1,n-1)
{
b[i]=a[i+1].x-a[i].x;
lyx[b[i]]++;
}
if(a[1].x==a[n].x||lyx[b[1]]==n-1) return printf("%d\n",a[1].id),0;
lyx[b[1]]--;
if(lyx[b[2]]==n-2) return printf("%d\n",a[1].id),0;
lyx[b[1]]++;
lyx[b[n-1]]--;
if(lyx[b[n-2]]==n-2) return printf("%d\n",a[n].id),0;
lyx[b[n-1]]++;
For(i,2,n-1)
{
int x=b[i];
int nxt=a[i+1].x-a[i-1].x;
int pre=b[i-1];
lyx[x]--,lyx[pre]--,lyx[nxt]++;
if(lyx[nxt]==n-2)
return printf("%d\n",a[i].id),0;
lyx[x]++,lyx[pre]++,lyx[nxt]--;
}
GG;
}