HDU 5419 细节处理

来源:互联网 发布:网络管理队伍状况 编辑:程序博客网 时间:2024/06/14 03:06

HDU 5419

题目链接:

题意:

给一个长度为n的序列,给m个区间。

问任意取三个区间,取三个区间中左端点最大值,右端点最小值,然后把这个区间(闭区间)的权值加起来,这样权值的期望是多少。

思路:

水题,统计到第几个数的时候在几个区间中。设在k个区间中,则总期望+=C(k,m)

现场赛的时候看到此题已晚。一般不贴会做的题,然而有一处TLE至今没想明白所以贴上。估计是数据过大爆了long long,然后负数的gcd无解。

源码:

#pragma comment(linker, "/STACK:1024000000,1024000000")

#include <iostream>

#include <iomanip>

#include <sstream>

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <cctype>

#include <ctime>

#include <climits>

#include <cassert>

#include <cmath>

#include <string>

#include <bitset>

#include <vector>

#include <deque>

#include <list>

#include <set>

#include <map>

#include <queue>

#include <stack>

#include <algorithm>

#include <functional>

#include <utility>

#include <numeric>

#define LL long long

#define gmax(a,b) ((a) > (b) ? (a) : (b))

#define gmin(a,b) ((a) < (b) ? (a) : (b))

#define MOD (1000000007)

//#define gcd(a,b) __gcd(a,b)

using namespace std;

const int MAXN = 50000 + 5;

int suml[MAXN], sumr[MAXN];

int val[MAXN];

int n, m;

LL gcd(LL a, LL b)

{

    if(a < b)

        return gcd(b, a);

    if(b == 0)

        return a;

    return gcd(b, a % b);

}

int main()

{

    int t;

    scanf("%d", &t);

    while(t--){

        scanf("%d%d", &n, &m);

        for(int i = 1 ; i <= n ; i++)

            scanf("%d", &val[i]);

        memset(suml, 0, sizeof(suml));

        memset(sumr, 0, sizeof(sumr));

        for(int j = 0 ; j < m ; j++){

            int u, v;

            scanf("%d%d", &u, &v);

            suml[u]++;

            sumr[v]++;

        }

        LL ans = 0;

        int tsum = 0;

        for(int i = 1 ; i <= n ; i++){

            tsum += suml[i];

            tsum -= sumr[i - 1];

//            printf("i = %d, tsum = %d\n", i, tsum);

            if(tsum >= 3){

//                printf("val[i] = %d, n = %d\n, tsum = %d\n", val[i], n, tsum);

                ans += val[i] * 1LL * (tsum) * (tsum - 1) / 2 * (tsum - 2) / 3;///这里也是哦~同下

            }

        }

        LL t2 = m * 1LL * (m - 1) / 2 * (m - 2) / 3;///这里不除以23Tshenmegui

        if(m <= 2 || ans == 0){

            printf("0\n");

            continue;

        }

        LL g = gcd(ans, t2);

        ans /= g;

        t2 /= g;

        if(t2 == 1)

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

        else

            printf("%I64d/%I64d\n", ans, t2);

    }

    return 0;

}

 

0 0