HDU - 5419 Victor and Toys(组合计数)

http://acm.hdu.edu.cn/showproblem.php?pid=5419

题意

n个物品,标号1-n,物品i有权值wi。现在有m个区间[l,r],从中任意选三个区间i,j,k,求物品编号在区间[ max{li,lj,lk},min{ri,rj,rk} ]的权值和,问总期望是多少。

分析

选择区间的总情况数为C(m,3)=m*(m-1)*(m-2)/6。对于物品,其存在贡献的地方一定是包含它的区间,那么先求出包含每个物品的区间数,用区间覆盖的思想,假设有num个区间包含权值为w的物品,那么此时它的总贡献就是w*C(num,3),只有三个都包含的同时选到才有效。注意使用long long

#include<iostream>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<map>
#include<set>
#define rep(i,e) for(int i=0;i<(e);i++)
#define rep1(i,e) for(int i=1;i<=(e);i++)
#define repx(i,x,e) for(int i=(x);i<=(e);i++)
#define X first
#define Y second
#define PB push_back
#define MP make_pair
#define mset(var,val) memset(var,val,sizeof(var))
#define scd(a) scanf("%d",&a)
#define scdd(a,b) scanf("%d%d",&a,&b)
#define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define pd(a) printf("%d\n",a)
#define scl(a) scanf("%lld",&a)
#define scll(a,b) scanf("%lld%lld",&a,&b)
#define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define IOS ios::sync_with_stdio(false);cin.tie(0)

using namespace std;
typedef long long ll;
template <class T>
void test(T a){cout<<a<<endl;}
template <class T,class T2>
void test(T a,T2 b){cout<<a<<" "<<b<<endl;}
template <class T,class T2,class T3>
void test(T a,T2 b,T3 c){cout<<a<<" "<<b<<" "<<c<<endl;}
const int N = 1e6+10;
//const int MAXN = 210;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fll;
const ll mod = 200907;
int T;
void testcase(){
    printf("Case #%d: ",++T);
}
const int MAXN = 1e5+5;
const int MAXM = 30;

ll gcd(ll a,ll b){
    return b==0?a:gcd(b,a%b);
}
ll C(ll n){
    return n*(n-1)*(n-2)/6;
}
int qu[MAXN],w[MAXN];
int main() {
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif // LOCAL
    int t,n,m,l,r;
    scd(t);
    while(t--){
        mset(qu,0);
        scdd(n,m);
        for(int i=1;i<=n;i++) scd(w[i]);
        for(int i=0;i<m;i++){
            scdd(l,r);
            qu[l]++,qu[r+1]--;
        }
        ll fenzi=0;
        int cnt=0;
        for(int i=1;i<=n;i++){
            cnt+=qu[i];
            if(cnt>=3) fenzi+=(w[i]*C(cnt));
        }
        ll fenmu=C(m);

        if(fenzi==0||fenmu==0){
            puts("0");
            continue;
        }
        ll d=gcd(fenmu,fenzi);
        if(d>0){
            fenzi/=d;
            fenmu/=d;

        }
        cout<<fenzi;
        if(fenmu==1) cout<<endl;
        else cout<<"/"<<fenmu<<endl;
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/fht-litost/p/9293001.html
今日推荐