HDU 5419 Victor and Toys ()

Victor and Toys

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/131072 K (Java/Others)
Total Submission(s): 467    Accepted Submission(s): 157


Problem Description
Victor has  n  toys, numbered from  1  to  n . The beauty of the  i -th toy is  wi .

Victor has a sense of math and he generates  m  intervals, the  i -th interval is  [li,ri] . He randomly picks  3  numbers  i,j,k(1i<j<km) , and selects all of the toys whose number are no less than  max(li,lj,lk)  and no larger than  min(ri,rj,rk) . Now he wants to know the expected sum of beauty of the selected toys, can you help him?
 

Input
The first line of the input contains an integer  T , denoting the number of test cases.

In every test case, there are two integers  n  and  m  in the first line, denoting the number of the toys and intervals.

The second line contains  n  integers, the  i -th integer  wi  denotes that the beauty of the  i -th toy.

Then there are  m  lines, the  i -th line contains two integers  li  and  ri .

1T10 .

1n,m50000 .

1wi5 .

1lirin .
 

Output
Your program should print  T  lines : the  i -th of these denotes the answer of the  i -th case.

If the answer is an integer, just print a single interger, otherwise print an irreducible fraction like  p/q .
 

Sample Input
  
  
1 3 4 1 1 5 2 3 1 3 3 3 1 1
 

Sample Output
  
  
5/4
 

Source
 

问题描述
Victor有nn个玩具,编号为11nn,其中编号为ii的玩具有w_iwi点有趣值。

Victor对数字特别敏感,他在头脑中生成了mm个区间,其中第ii个区间为[l_i,r_i][li,ri],并随机选取了33个互不相同的数i,j,k(1\leq i < j < k \leq m)i,j,k(1i<j<km),将所有满足\max(l_i,l_j,l_k)\leq x\leq \min(r_i,r_j,r_k)max(li,lj,lk)xmin(ri,rj,rk)的编号为xx的玩具取出,他想知道他取出的玩具的有趣值之和的期望是多少,你能帮帮他吗?
输入描述
第一行包含一个整数TT,表示测试数据的组数。

每组测试数据的第一行有两个整数nn, mm,表示玩具的个数和区间的个数。

接下来一行有nn个数,其中第ii个数为w_iwi。

接下来mm行,每行两个整数,其中第ii行表示l_ili, r_iri1\leq T\leq 101T101\leq n,m\leq 500001n,m500001\leq w_i\leq 51wi51\leq l_i\leq r_i\leq n1lirin
输出描述
每组测试数据输出一行,若答案为整数,则输出一个整数,否则输出形如p/qp/q的最简分数。
输入样例
1
3 4
1 1 5
2 3
1 3
3 3
1 1
输出样例
5/4


解题思路:和的期望 = (∑任意一种挑选方式的和x)/(满足i<=j<=k的挑选方式的总数y) = x / y 。分母y 就是m个数中取3个数的组合C(m,3),即y = m*(m-1)*(m-2)/6 ,对于分子x,如果第i个数出现的区间数是num(简言之就是有num个区间包含第i个数),那么第i个数对分子的贡献值是w[i]*C(num,3)。因此枚举i,累加和。(预处理过程与HDU 5124 line 类似)

代码如下:
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <string>
#include <algorithm>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <fstream>
#include <limits.h>
#include <ctime>
#define debug "output for debug\n"
#define pi (acos(-1.0))
#define eps (1e-6)
#define inf (1<<28)
#define sqr(x) (x) * (x)
#define mod 1000000007
using namespace std;
typedef long long ll;
typedef unsigned long long ULL;
int w[50005],dp[50005];
ll gcd(ll a,ll b)
{
    return b==0?a:gcd(b,a%b);
}
int main()
{
    ll i,j,k,n,m,l,r,t;
    scanf("%I64d",&t);
    while(t--)
    {
        scanf("%I64d%I64d",&n,&m);
        for(i=1;i<=n;i++)
            scanf("%I64d",&w[i]);
        memset(dp,0,sizeof(dp));
        for(i=0;i<m;i++)
        {
            scanf("%I64d%I64d",&l,&r);
            dp[l]++;
            dp[r+1]--;
        }
        ll x=0;
        ll num=0;
        for(i=1;i<=n;i++)
        {
            num+=dp[i];
            if(num>=3)
                x+=num*(num-1)*(num-2)/6*w[i];
        }
        ll y=m*(m-1)*(m-2)/6;
        //printf("x=%I64d y=%I64d\n",x,y);
        ll d=gcd(x,y);
        if(d)
        {

            x=x/d;
            y=y/d;
            if(y==1)
                printf("%I64d\n",x);
            else
                printf("%I64d/%I64d\n",x,y);
        }
        else
            printf("0\n");
    }
    return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值