HDU 5720 Wool

a[1],a[2],a[3],a[4],a[5]。。。。。a[n]。

可以先计算不符合要求的有几种,然后总数-不符合的=符合的。

不符合的就是能构成三角形的有几种。

看一个例子:

a[1]与a[5]能写出构成三角形的条件。

a[2]与a[5]能写出构成三角形的条件。

a[3]与a[5]能写出构成三角形的条件。

a[4]与a[5]能写出构成三角形的条件。

但是,a[4]与a[5]能写出的范围比之前任何一个都大,所以之前的都可以省略。

也就是说,只要a[i]与a[i-1]建立约束条件即可。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#include<queue>
#include<stack> 
#include<algorithm>
using namespace std;

const int maxn=400000+10;
int T,n;
long long L,R;
long long a[maxn];
struct Seg
{
    long long ll,rr;
}s[maxn],t[maxn];
int sz,cnt;

bool cmp(const Seg&a,const Seg&b)
{
    return a.ll<b.ll;
}

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%lld%lld",&n,&L,&R);
        for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
        sort(a+1,a+1+n);
        sz=0;
        for(int i=1;i<n;i++)
        {
            long long LL,RR;
            LL=a[i+1]-a[i]+1;
            RR=a[i+1]+a[i]-1;
            s[sz].ll=LL; s[sz].rr=RR; sz++;
        }

        sort(s,s+sz,cmp);

        if(sz==0) { printf("0
"); continue; }
        cnt=0;

        t[0].ll=s[0].ll; t[0].rr=s[0].rr;
        for(int i=1;i<sz;i++)
        {
            if(s[i].ll>=t[cnt].ll&&s[i].ll<=t[cnt].rr)
                t[cnt].rr=max(t[cnt].rr,s[i].rr);
            else
            {
                cnt++;
                t[cnt].ll=s[i].ll;
                t[cnt].rr=s[i].rr;
            }
        }

        long long ans=0;
        for(int i=0;i<=cnt;i++)
        {
            if(t[i].rr<L) continue;
            if(t[i].ll>R) continue;
            long long LL=max(L,t[i].ll);
            long long RR=min(R,t[i].rr);
            ans=ans+(RR-LL+1);
        }
        printf("%lld
",R-L+1-ans);

    }
    return 0;
}
原文地址:https://www.cnblogs.com/zufezzt/p/5682169.html