牛客练习赛 3 E

题目链接

题目描述:
𝑅𝑒𝑘𝑖是一名狙击手,凭借肉眼视觉可以做到精确命中绝对半径2051公尺的一切目标。
作为一名优秀的狙击手,𝑅𝑒𝑘𝑖不仅经常保养枪支,也经常保养弹药。
𝑅𝑒𝑘𝑖有𝑛枚子弹,第𝑖枚的型号为𝐶𝑖,𝑅𝑒𝑘𝑖打算扔掉其中最多𝑘枚。
大多数优秀的狙击手都有艺术癖好,𝑅𝑒𝑘𝑖希望扔掉一部分子弹后,最
长的连续相同子弹序列的长度尽量长。
输入格式:
第一行,两个整数𝑛,𝑘。0<=n,k<=1e5
第二行,𝑛个正整数𝐶𝑖。1<=Ci<=1e9
输出格式:
一行,一个整数,最长的连续相同子弹序列的长度。

解题报告:
首先离散化 O(nlogn)
在用vector依次记录每种出现的位置,很明显答案的区间具有单调性,故可用二分来做,以vector记录位置为右端点,二分左端点即可。

#define first f
#define second s
#define ll long long
#define mp make_pair
#define pb push_back
#define pf push_front
#define lb lower_bound
#define ub upper_bound
#include <bits/stdc++.h>
#define pii pair<int,int>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=1e5+5;
const int MOD=998244353;
const double PI=acos(-1);
const double e=2.718281828459;
 
pii p[maxn];
int d[maxn];
vector<int>v[maxn];
bool cmp(pii a,pii b)
{
    if(a.f==b.f){return a.s<b.s;}
    return a.f<b.f;
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&p[i].f);
        d[i]=p[i].f;
        p[i].s=i;
    }
    sort(p+1,p+n+1,cmp);
    int id=1;
    d[p[1].s]=id;
    for(int i=2;i<=n;i++){
        if(p[i].f==p[i-1].f){
            d[p[i].s]=id;
        }
        else{
            d[p[i].s]=++id;
        }
    }
    for(int i=1;i<=n;i++){
        v[d[i]].pb(i);
    }
    int mx=-1;
    for(int i=1;i<=id;i++){
        for(int j=0;j<v[i].size();j++){
            int l=0,r=j,ans=0;
            while(l<=r){
                int mid=(l+r)>>1;
                if(v[i][j]-v[i][mid]+1<=(j-mid+1)+m){
                    ans=mid;r=mid-1;
                }
                else{
                    l=mid+1;
                }
            }
            mx=max(mx,j-ans+1);
        }
    }
    printf("%d\n",mx);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值