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 ",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; }