您的位置:首页 > 其它

HDU 5381 The sum of gcd

2015-08-13 20:01 411 查看
对于每个i,求出若干区间[l1,r1],[l2,r2],[l3,r3]...满足gcd(l1~i)~gcd(r1~i)一样,gcd(l2~i)~gcd(r2,i)一样...

则以i为右区间的所有gcd和为sum[i] = (r1 - l1 + 1) * g1 + (r2 - l2 + 1) * g2 + ...

同理求出i右边的一段段同gcd区间[l11,r11],[l22,r22],[l33,r33]...

然后将询问按左区间排序,int p初始设为1,对于p <= i < L,要消除i对所有前缀和的影响,只要[l11,r11]的sum[]减去g11,[l22,r22]的sum[]减去g22...

p = L

ans = [L,R]的sum和

求i的区间时,先保留i-1求出的区间,然后A[i]和每个区间的g求gcd,该合并的合并

(队友A的,就不贴他优雅的代码了, 红红火火恍恍惚惚)

struct Node {
int l, r, g;

Node() {}
Node(int l, int r, int g):
l(l), r(r), g(g) {
}
}nodes
;

int m = 0;
for(int i = 1; i <= n; i ++) {
rep(j, m) {
nodes[j].g = std::__gcd(nodes[j].g, a[i]);
}
nodes[m ++] = Node(i, i, a[i]);
int t = 0;
for(int j = 1; j < m; j ++) {
if(nodes[j].g == nodes[t].g) {
nodes[t].r = nodes[j].r;
} else {
nodes[++ t] = nodes[j];
}
}
t++;
m = t;
LL sum = 0;
rep(j, m) {
sum += (nodes[j].r - nodes[j].l + 1LL) * nodes[j].g;
}
Stree.L = i;
Stree.R = i;
Stree.val = sum;
Stree.update(1, n, 1);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  HDU 5381 The sum of gcd