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\n"); 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\n",R-L+1-ans); } return 0; }