2021 Niu Guest Winter Holiday Algorithm Basic Training Camp 4D Problem-Wen Cheying's Dog

Question link
Insert picture description here
solution:

To solve this problem, you must know that the intimacy ≤ \leqHow many logarithms d are, but cannot forcefully calculate how many pairs there are in different colors, because it will time out, so tolerance and exclusion are needed. That is, the number of different colors = all-the same color.

Number of all pairs = d + d + d +.... + D − 1 + d − 2 + 1 + 0 = d+d+d+....+d-1+d-2+1+0=d+d+d+....+d1+d2+1+0 , it can be directly calculated. To calculate the same color pairs, first put all the same color together, you can save it with a vector, and then use a double pointer to calculate the number of the same color pairs.

The next step is dichotomy. What is the k-th degree of intimacy after the dichotomy? If you know the intimacy, you can directly o (n) o(n)o ( n ) Find all pairs whose intimacy is d, and then sort them to know what the k-th is.

Code:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<set>
#include<ctime>
#define iss ios::sync_with_stdio(false)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int,int>pii;
const int MAXN=1e5+5;
const int mod=1e9+7;
const int inf=0x3f3f3f;
int a[MAXN];
ll sum[MAXN];
std::vector<int>v[MAXN];
map<int ,int >mp;
struct node
{
    
    
    int x,y;
}f[MAXN];
bool cmp(node aa,node bb)
{
    
    
    if(aa.x==bb.x) return aa.y<bb.y;
    else return aa.x<bb.x;
}
int main()
{
    
    
    int n;ll k;
    scanf("%d%lld",&n,&k);
    int cnt=0;
    for(int i=1;i<=n;i++)
    {
    
    
        scanf("%d",&a[i]);
        if(!mp.count(a[i]))
        {
    
    
            mp[a[i]]=++cnt;
        }
        v[mp[a[i]]].push_back(i);
    }
    for(int i=1;i<=n-1;i++)
    {
    
    
        sum[i]=1ll*(n-i)*i;
        sum[i]+=1ll*i*(i-1+0)/2;
    }
    int l=1,r=n-1;
    int pos=-1;
    ll cal;
    while(l<=r)
    {
    
    
        int mid=(l+r)>>1;
        ll ans=0;
        for(int i=1;i<=cnt;i++)
        {
    
    
            if(v[i].size()==1) continue; 
            int pos1=0,pos2=1;
            int len=v[i].size();
            while(1)
            {
    
    
                while(pos2<len&&v[i][pos2]-v[i][pos1]<=mid)
                {
    
    
                    ans+=pos2-pos1;
                    pos2++;
                }
                if(pos2==len) break;
                while(pos1<pos2&&v[i][pos2]-v[i][pos1]>mid) pos1++;
            }
        }
        ll res=sum[mid]-ans;
        if(res>=k)
        {
    
    
            pos=mid;
            cal=res;
            r=mid-1;
        }
        else l=mid+1;
    }
    if(pos==-1)
    {
    
    
        printf("-1\n");
        return 0;
    }
    int cot=0;
    for(int i=1;i+pos<=n;i++)
    {
    
    
        if(a[i]!=a[i+pos])
        {
    
    
            f[++cot].x=i;
            f[cot].y=i+pos;
        }
    }
    sort(f+1,f+cot+1,cmp);
    for(int i=1;i<=cot;i++)
    {
    
    
        if(cal-cot+i==k)
        {
    
    
            printf("%d %d\n",f[i].x,f[i].y);
            return 0;
        }
    }
}

Guess you like

Origin blog.csdn.net/weixin_45755679/article/details/113874529