TopCoder Open 2016 R2B

300

  這題讓計算三條邊分別不超過abc 的三角形有多少個,數據範圍1e9 ,比賽時寫了個O(1e9) 的,悲慘爆零。
  正確的做法是利用容斥原理O(1) 。如果三條邊可以是不超過abc 的任何數,答案就是abc ,但是肯定有些情況是非法的,只需要考慮兩邊長度大於等於第三邊就行了,把非法的減去就是答案。具體的計算過程還是需要細心推一下的,只需要很基本的數學知識就能夠推出來(但是我補題的時候還是調了很久)。
  總結一下,當計算某些值比較困難(合法情況),但是反過來比較簡單的時候(總數和非法情況),就可以考慮容斥。

#include <bits/stdc++.h>
using namespace std;

#define ll long long

const ll mod = 1000000007;

// *inv%mod 相當於/6 
const ll inv = 166666668;

const ll LARGE = 3e18;

ll calc(ll n){
    ll res = n*(n+1);
    res %= mod;
    res *= (2*n+1);
    res %= mod;
    res *= inv;
    res %= mod;
    return res;
}

ll solve(ll a,ll b,ll c){
    ll res = 0;

    ll MIN = min(a,b);
    ll MAX = max(a,b);
    ll tmp = 0;

    // part 1
    if(c>1){
        ll end = min(MIN,c-1);
        tmp += end*(1+end)/2;
        tmp %= mod;
        tmp *= c;
        tmp -= calc(end);
        tmp %= mod;
        tmp += mod;
        tmp %= mod;
        res += tmp;
        //cout<<"part 1 = "<<tmp<<endl; 
    }
    // part 1 end

    // part 2
    tmp = 0;
    ll l = MIN+2;
    ll r = min(c,MAX+1);
    ll cnt = r-l+1;
    if(cnt>0){
        tmp += ((c-l+1)+(c-r+1))*cnt/2;
        tmp %= mod;
        tmp *= MIN;
        tmp %= mod;
        res += tmp;
        //cout<<"part 2 = "<<tmp<<endl;
    }
    // part 2 end

    // part 3
    if(c>MAX+1){
        tmp = 0;
        ll cnt = min(MIN,c-MAX)-1;

        tmp += (MIN-1+(MIN-cnt))*cnt/2;
        tmp %= mod;
        tmp *= (c-MAX);
        tmp %= mod;
        tmp += calc(cnt);
        tmp %= mod;
        tmp -= MIN*((1+cnt)*cnt/2%mod);
        tmp %= mod;
        if(tmp<0){
            tmp += mod;
        }
        res += tmp;
        //cout<<"part 3 = "<<tmp<<endl;
    }
    // part 3 end

    res %= mod;
    return res;
}


class TriangleTriples{
public:
    int count(ll A, ll B, ll C){
        ll res = A*B;
        res %= mod;
        res *= C;
        res -= (solve(A,B,C) + solve(C,A,B) + solve(B,C,A))%mod;
        res %= mod;
        res += mod;
        res %= mod;
        return res;
    }
};


發佈了455 篇原創文章 · 獲贊 16 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章