您的位置:首页 > 其它

【hdu5419】Victor and Toys

2015-08-23 13:54 330 查看
求求求

搞搞搞

搞法如下:考虑每个数w[i]w[i]对答案的贡献,呃。。。首先答案一定是∑[...](m3)\sum [...]\over {m\choose 3}的形式,只需要搞分子就好了。然后考虑每个数w[i]w[i]对分子的贡献,假设一个点被kk个区间所覆盖,那么它的贡献就是w[i]∗(k3)w[i]*{k\choose 3}当然,当k≤2k\le2时认为它为00就可以统一处理。于是只需要对每个点算出被多少区间覆盖即可。窝用了两个BITBIT统计,对给定的区间(u,v)(u,v),窝们把它看成左右括号的形式,当所有括号都在数轴上标记出来以后,窝们怎么统计嘞?可以发现,一个点被覆盖的次数就是该点左边所有左括号的数量减去右括号的数量!另外需要注意,如果一个括号的左右部分都落在这个点上的处理,考虑到这种情况,窝们将上述数量修正为:区间[1,x][1,x]的左括号数量−-区间[1,x−1][1,x-1]的右括号数量。直接统计即可得到答案。值得注意的是,只考虑分子部分,极限情况是5000050000个55,且含5000050000个区间,均为[1,50000][1,50000],那么分子为5∗50000∗(500003)<500004=625∗1016<263−15*50000*{50000\choose 3}\lt {50000}^4=625*{10}^{16}\lt2^{63}-1是不需要担心会超出long longlong\ long的表示范围的。

/* **********************************************

File Name: 5419.cpp

Auther: zhengdongjian@tju.edu.cn

Created Time: 2015/8/23 星期日 下午 1:35:01

*********************************************** */
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> P;
#ifdef ONLINE_JUDGE
#define lld I64d
#endif

typedef long long ll;
const int MAX = 50007;

int a[MAX];
int sum[2][MAX]; //BIT. sum[0] goes up, sum[1] goes down.

inline int lb(int& x) {
return x & (-x);
}

int query(int id, int x) {
int s = 0;
while (x > 0) {
s += sum[id][x];
x -= lb(x);
}
return s;
}

void modify(int id, int x, int ad) {
while (x < MAX) {
sum[id][x] += ad;
x += lb(x);
}
}
//return C(x,3)
inline ll gao1gao(ll x) {
return x * (x - 1) * (x - 2) / 6;
}

inline void read(int& x) {
char c;
while ((c = getchar()) < '0' || c > '9');
x = c - '0';
while ((c = getchar()) >= '0' && c <= '9') {
x = (x << 1) + (x << 3) + c - '0';
}
}

int main() {
int T;
read(T);
while (T--) {
int n, m;
read(n);
read(m);
memset(sum, 0, sizeof(sum));
for (int i = 1; i <= n; ++i) {
read(a[i]);
}
int u, v;
for (int i = 1; i <= m; ++i) {
read(u);
read(v);
modify(0, v, 1);
modify(1, u, 1);
}

ll ans = 0LL;
for (int i = 1; i <= n; ++i) {
ans += gao1gao(query(1, i) - query(0, i - 1)) * a[i];
}
if (ans == 0) {
puts("0");
continue;
}
ll y = gao1gao(m);
ll gcd = __gcd(ans, y);
ans /= gcd;
y /= gcd;
if (y == 1LL) {
printf("%lld\n", ans);
} else {
printf("%lld/%lld\n", ans, y);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: