zoukankan      html  css  js  c++  java
  • 温澈滢的狗狗 题解(二分+双指针)

    题目链接

    题目思路

    首先要看清亲密度为下标差写了一年假题

    然后显然是要二分亲密度的

    如何计算这个小于等于这个亲密度的对数

    利用容斥和用总点对数-同色对数

    总点对数为\((n-x)*x+(1+x-1)*(x-1)/2\)

    同色对数利用双指针求解

    然后知道亲密度\(O(n)\)扫一遍即可

    代码

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define debug cout<<"I AM HERE"<<endl;
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    const int maxn=1e5+5,inf=0x3f3f3f3f;
    const double eps=1e-3;
    const ll mod=1004535809;
    int n;
    int a[maxn],cnt[maxn];
    ll k;
    ll cal(int x){
        memset(cnt,0,sizeof(cnt));
        ll sum=1ll*(n-x)*x+1ll*(1+x-1)*(x-1)/2;
        for(int i=1;i<=n;i++){
            sum-=cnt[a[i]];
            cnt[a[i]]++;
            if(i>x){
                cnt[a[i-x]]--;
            }
        }
        return sum;
    }
    signed main(){
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        int l=1,r=n,ans=-1;
        while(l<=r){
            int mid=(l+r)/2;
            if(cal(mid)>=k){
                ans=mid;
                r=mid-1;
            }else{
                l=mid+1;
            }
        }
        if(ans==-1){
            printf("-1\n");
            return 0;
        }
        int pos=k-cal(ans-1);
        for(int i=1;i<=n;i++){
            if(i+ans<=n&&a[i+ans]!=a[i]){
                pos--;
                if(pos==0){
                    printf("%d %d\n",i,i+ans);
                    break;
                }
            }
        }
        return 0;
    }
    // 3 2 1 2 3
    //6 3
    //1 2 3 4 5 6
    
    
    不摆烂了,写题
  • 相关阅读:
    取球问题
    汉字首字母
    上三角
    循环小数
    拓扑排序
    倒水
    equals方法使用技巧
    Java库中的集合
    win10安装Redis方法以及基本配置
    c、c++函数随机
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/14427194.html
Copyright © 2011-2022 走看看