hdu5419 Victor and Toys 期望,差分前缀和

来源:互联网 发布:htc g16软件下载 编辑:程序博客网 时间:2024/05/19 02:30

期望的分母是C(m,3),利用差分前缀和处理出每个点被多少区间覆盖,w[i]*C(sum[i],3)即为第i位的贡献。

学习一下期望的求法考虑每个点的贡献。

#include<iostream>#include<cstring>#include<cstdio>#include<ostream>#include<istream>#include<algorithm>#include<queue>#include<string>#include<cmath>#include<set>#include<map>#include<stack>#include<vector>#define fi first#define se second#define ll long long#define pii pair<ll,ll>#define inf (1ll<<50)#define eps 1e-8#define pb push_backusing namespace std;const int maxn=110005;int n,m;int d[maxn];int sum[maxn];ll C(int a){    if(a<3)        return 0;    return (ll)a*(a-1)*(a-2)/6;}ll gcd(ll a,ll b){    return b==0?a:gcd(b,a%b);}int main(){    int t;    scanf("%d",&t);    int l,r;    while(t--) {        memset(sum,0,sizeof(sum));        scanf("%d%d",&n,&m);        for(int i=1;i<=n;i++)            scanf("%d",&d[i]);        for(int i=1;i<=m;i++) {            scanf("%d%d",&l,&r);            sum[l]++;            sum[r+1]--;        }        sum[0]=0;        for(int i=1;i<=n;i++)            sum[i]=sum[i-1]+sum[i];        ll a=0;        for(int i=1;i<=n;i++) {            a+=C(sum[i])*d[i];        }        ll b=C(m);        if(a==0 || b==0) {            printf("0\n");        }        else {            if(a%b==0)                printf("%I64d\n",a/b);            else {                ll g=gcd(a,b);                printf("%I64d/%I64d\n",a/g,b/g);            }        }    }    return 0;}


0 0