cf1119d Frets On Fire 前缀和+二分

Posted myrtle

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cf1119d Frets On Fire 前缀和+二分相关的知识,希望对你有一定的参考价值。

题目:http://codeforces.com/problemset/problem/1119/D

题意:给一个数n,给出n个数组的第一个数(a[0]=m,a[1]=m+1,a[2]=m+2,...,a[n]=m+n),给定q个查询,每个查询问所有数组的[l,r]区间内总共出现了多少个不同的数。

思路:答案与给出查询的区间无关,只与区间长度有关。

 

两数组不重复的数与数组第一个数的差、区间长度有关。两数组内不重复的数为min(两数组a[0]之差,区间长度)。

因此对数组第一个数进行sort,之和求出数组第一位之差delta[],再按照升序排序,小于区间长度的都取delta[],大于区间长度的都取len。

然后对delta求一下前缀和sum,查找的时候对delta进行二分。

技术图片

 

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
long long s[maxn]={0},delta[maxn]={0},sum[maxn]={0}; 
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)scanf("%lld",&s[i]);
    sort(s,s+n);
    for(int i=0;i<n-1;i++)delta[i]=s[i+1]-s[i];
    sort(delta,delta+n-1);
    for(int i=0;i<n;i++)
    {
        sum[i+1]=sum[i]+delta[i];
    }
    
    int q;
    scanf("%d",&q);
    for(int i=0;i<q;i++)
    {
        long long l,r,len,ans=0;
        scanf("%lld%lld",&l,&r);
        len=r-l+1;
        int p=upper_bound(delta,delta+n-1,len)-delta;
        ans=sum[p]+len*(n-p);
        if(i!=q-1)printf("%lld ",ans);
        else printf("%lld
",ans);
    }
    return 0; 
} 

 

以上是关于cf1119d Frets On Fire 前缀和+二分的主要内容,如果未能解决你的问题,请参考以下文章

[CF484E]Sign on Fence

CSU-2031 Barareh on Fire

Codeforces 1119D(贡献计算)

[Vue 警告]:v-on 处理程序中的错误:“TypeError:无法读取未定义的属性 'fire'”

链式前向星上DFS(Pants On Fire)

CF873B 前缀和+map