https://codeforces.com/problemset/problem/1185/D
思路:
考虑去掉一个数后序列里面差分的情况有多少个不同的数字。
开始用multiset,但是常数太大,8*logn*logn,哪怕去掉了一些卡multiset的情况仍然tle41
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=2e5+100;
typedef int LL;
inline LL read(){LL x=0,f=1;char ch=getchar(); while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
struct P{
LL val,id;
}a[maxn];
bool cmp(P A,P B){return A.val<B.val;}
multiset<LL>s;
set<LL>sss;
int main(void)
{
LL n;n=read();
for(LL i=1;i<=n;i++) a[i].val=read(),a[i].id=i;
sort(a+1,a+1+n,cmp);
for(LL i=1;i<n;i++){
s.insert(a[i+1].val-a[i].val);
sss.insert(a[i+1].val-a[i].val);
}
///LL num1=s.count( (*s.begin()));
///LL num2=s.count( (*s.end()) );
if(sss.size()>=4){
printf("-1\n");
return 0;
}
bool flag=1;
LL last=a[1].val;
for(LL i=1;i<=n;i++){
if(i>1&&a[i].val==last&&a[i+1].val==last) {
last=a[i].val;
continue;
}
if(i<n) s.erase(s.find(a[i+1].val-a[i].val));
if(i>=2) s.erase(s.find(a[i].val-a[i-1].val));
if(i>=2&&i<n) s.insert(a[i+1].val-a[i-1].val);
/*for(auto j:s){
cout<<j<<" ";
}
cout<<"\n";*/
if(s.count( ( *s.begin() ) )==s.size()){
flag=0;
printf("%d\n",a[i].id);
break;
}
if(i<n) s.insert(a[i+1].val-a[i].val);
if(i>=2) s.insert(a[i].val-a[i-1].val);
if(i>=2&&i<n) s.erase(s.find(a[i+1].val-a[i-1].val));
last=a[i].val;
}
if(1==flag) printf("-1\n");
return 0;
}
所以还是需要转化。
改成维护该数字出现第一次和消失的情况。然后map维护。
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=2e5+100;
typedef int LL;
inline LL read(){LL x=0,f=1;char ch=getchar(); while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
struct P{
LL val,id;
}a[maxn];
LL dif=0;
map<LL,LL>map1;
bool cmp(P A,P B){return A.val<B.val;}
void add(LL v){
map1[v]++;
if(map1[v]==1) dif++;
}
void rem(LL v){
map1[v]--;
if(map1[v]==0) dif--;
}
int main(void)
{
LL n;n=read();
for(LL i=1;i<=n;i++) a[i].val=read(),a[i].id=i;
sort(a+1,a+1+n,cmp);
for(LL i=1;i<n;i++){
add(a[i+1].val-a[i].val);
}
///LL num1=s.count( (*s.begin()));
///LL num2=s.count( (*s.end()) );
if(map1.size()>=4){
printf("-1\n");
return 0;
}
bool flag=1;
LL last=a[1].val;
for(LL i=1;i<=n;i++){
/*if(i>1&&a[i].val==last&&a[i+1].val==last) {
last=a[i].val;
continue;
}*/
if(i<n) rem( a[i+1].val-a[i].val);
if(i>=2) rem( a[i].val-a[i-1].val);
if(i>=2&&i<n) add( a[i+1].val-a[i-1].val);
/*for(auto j:map1){
cout<<j.first<<" "<<j.second<<"\n";
}
cout<<"\n";*/
if(dif<=1){
flag=0;
printf("%d\n",a[i].id);
break;
}
if(i<n) add(a[i+1].val-a[i].val);
if(i>=2) add(a[i].val-a[i-1].val);
if(i>=2&&i<n) rem( a[i+1].val-a[i-1].val);
///last=a[i].val;
}
if(1==flag) printf("-1\n");
return 0;
}