【Codechef】シェフと三角形-Problemコード:MAKETRI

質問表面:

  暁明は単純すぎる彼のために調理し、調理するのに疲れていました。その日、彼は自分自身に挑戦することを決めました。彼が選択したNの一品を行う準備ができルートパスタを、。彼が選択する必要があるパスタ、パスタは、できることをルートと、既存のN個のルート面2つのフォーム三角形パスタの長さに選択されなければならない[L、R]の範囲内。暁明選択見つけてください番号スキームを

入力:

  最初の行は、N、L、Rを与えます 二行目は、数N LEN1、LEN2、...、lenNを与え、Nは、パスタの長さを示します。

  2 <= N <= 1E6 1 <= L、R <= 1e18,1 <=レニ<= 1E18

出力:

  出力ソリューションの数。

例:

INPUT:
5 1 4 
1 2 3 4 5 
出力:
3 

このタイトルカード私に長い時間。すべての後、私は前に話題のこの種を行っていません。

あるいはタイトルの意味は単純であり、しかし、三角アレイの数を補うために、所与の道路番号の選択された側面を範囲とすることができる[L、R]です
自然のデータサイズは、すべての後に、暴力ではありませんO(N2)プラスサイズ1E6が爆発するバインドされて参照してください。

まず、タイトルがスクレープ三角形にした後、我々は避けられない自然の三角形と考えることができます:
1、第3の辺のうちの任意の2つの側面がより大きい
任意の二つの辺の間の差未満2.第3辺がされ

、我々は[L、R]のXを取ると仮定アレイの辺の長さの長さ、及びその後からは、所定のエッジ長AiとAjとを取ります。
簡単に次の式を得るために:
・X- +愛>をAjと- > X-> Ajと-愛
・X- + Ajと>愛- > X->愛- Ajと
・愛+ Ajと> X - > X- <愛+ Ajと
についてなぜ、これらの3つの式は、実際には、あなたも、このにも、他の3を書くことができている、私はちょうどそのようなA式の便宜のために取りました。

我々は自然に出てくることができるように、[L、R]及びプログラムX [マックス(AI-Ajと、多数の AJ-AI)+1、愛+ AJ-1]は、選択さAiとAjとの交点です。
交差点の両方ことが上記の手段だけでなく、組成物は[L、R]の範囲でAiとAjとを有する三角形とすることができる範囲。

しかし、どのように選択したAiとAjと程度はまだ確かに問題です。結局のところ、もし暴力またはO((R-L + 1 )* N 2)。
ここでは非常に重要な結論を紹介:

3つの数字があると仮定A1 <A2 <A3は、我々が定義するR(i、j)が三角形の範囲愛を表し、Ajが形成することができます。
したがって、
  R&LT(1,2)= [A1-A2。1 +、A2 + A1-1]、
  R&LT(2,3)= [+ A3-A2。1、A3 + A2-1]
  R&LT(1,3)= [ A3-A1 + 1、A3 + A1-1]。
R(2,3)は完全にのR(1,3)に含まれています。これは良いのより証拠である、すべての後に、2 より大きいと、より類似する数の範囲によって形成される三角形は、より良好な2以上でなければならない遠くから小さい多数あります。
(具体例としては証明することができる)

、我々はRの対(J-1、j)とコレクタ(1-N N-1及びjの合計を通過した後のn-1の第1のアレイをソートすることができ、この結論にJ-1)、次いでプログラムはを要求することができる、すなわち、交差点の[L、R]所定数。
しかし、に注意を払うようにしてください、特別な事情、またはWAの多くを送信します。

以下は、ACコードです:
#include<bits/stdc++.h>
#define ll long long
using namespace std;

int main()
{
    long long n,l,r;
    scanf("%lld %lld %lld",&n,&l,&r);

    ll a[n];

    for(ll i=0;i<n;i++)
    scanf("%lld",&a[i]);
    sort(a,a+n);

    ll sum,diff,ans=0;
    if (l > r)
    {
        cout << ans << endl;
        return 0;
    }

    for(ll i=n-1;i>0;i--)
    {
        sum = a[i]+a[i-1]-1;
        diff = a[i]-a[i-1]+1;
        //这里直接求交集
        ll s = max(l,diff);
        ll d = min(sum,r);
        if (s <= d)
            ans += d-s+1;
        //把选用过的长度去掉
        r = min(r,diff-1);
    }

    printf("%lld\n",ans);

    return 0;
}
View Code

おすすめ

転載: www.cnblogs.com/Vikyanite/p/12177631.html