分母是一定的C(m,3) 树状数组求每个数可以在那些段中出现,若x出现在了s段中,分子加上w[x]*C(s,3)
1 3 4 1 1 5 2 3 1 3 3 3 1 1
5/4
/* *********************************************** Author :CKboss Created Time :2015年08月23日 星期日 14时23分47秒 File Name :HDOJ5419.cpp ************************************************ */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <cmath> #include <cstdlib> #include <vector> #include <queue> #include <set> #include <map> using namespace std; typedef unsigned long long int LL; const int maxn=50500; /****************BIT***********************/ int n,m; int w[maxn]; int l[maxn],r[maxn]; inline int lowbit(int x) { return x&(-x); } int tree[maxn]; void add(int p,int v) { for(int i=p;i<maxn;i+=lowbit(i)) tree[i]+=v; } int sum(int p) { int ret=0; for(int i=p;i;i-=lowbit(i)) ret+=tree[i]; return ret; } LL getC(LL x) { return x*(x-1)/2LL*(x-2)/3LL; } LL gcd(LL a,LL b) { if(b==0) return a; return gcd(b,a%b); } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int T_T; scanf("%d",&T_T); while(T_T--) { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",w+i); memset(tree,0,sizeof(tree)); for(int i=0;i<m;i++) { scanf("%d%d",l+i,r+i); add(l[i],1); add(r[i]+1,-1); } if(m<3) { puts("0"); continue; } LL up=0,down=getC(m); for(int i=1;i<=n;i++) { LL x=sum(i); if(x>=3) { up=up+w[i]*getC(x); } } if(up==0) { puts("0"); continue; } LL g=gcd(up,down); if(g==down) cout<<up/g<<endl; else cout<<up/g<<"/"<<down/g<<endl; } return 0; }