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的,就不贴他优雅的代码了, 红红火火恍恍惚惚)
则以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 1568
- HDU1290
- HDU1568(Fobonacci公式)
- HDU ACM Step 2.2.2 Joseph(约瑟夫环问题)
- HDU 1405
- HDU 1297
- hdu 1205
- hdu 2087
- hdu 1016
- HDU 4898 The Revenge of the Princess’ Knight ( 2014 Multi-University Training Contest 4 )
- HDU 1000
- HDU 1001
- HDU 1622 Trees On The Level
- HDU 1063 Exponentiation
- Hdu5033
- HDU 1166 敌兵布阵
- HDU Rightmost Digit
- hdu 1002
- 贪心 hdu 1003
- hdu 1004