D. Extra Element(思维+map)

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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值