HDU 4407 Sum ★(容斥原理)
2012-11-29 20:14
369 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4407
题目大意:给定初始n个数1..n,两个操作,①1 x y p 询问第x个数到第y个数中与p互质的数的和; ②:2 x y 把第x个数变成y
思路:容斥原理求数区间[1..r]中与n互质的数的(个数&&和):HDU 4135
解决它的逆问题:求[1..r]中与n不互质的数的个数.
考虑n的素因子pi,则[1..r]中与pi不互质的数的个数是[r/pi].
然而,如果我们单纯将所有结果相加,会得到错误答案。有些数可能被统计多次(被好几个素因子整除)。所以,我们要运用容斥原理来解决。
我们可以用2^k的算法求出所有的pi组合,然后计算每种组合的pi乘积,通过容斥原理来对结果进行加减处理。
回到此题中,求个数和求和是一样的,我们只需要考虑怎么处理第二个操作——因为这道题m给的很小,所以我们完全可以每次询问都枚举以前改变的情况,至此问题解决。注意一点就是同一个地方的数可能被改两次,所以用map映射处理比较好。
题目大意:给定初始n个数1..n,两个操作,①1 x y p 询问第x个数到第y个数中与p互质的数的和; ②:2 x y 把第x个数变成y
思路:容斥原理求数区间[1..r]中与n互质的数的(个数&&和):HDU 4135
解决它的逆问题:求[1..r]中与n不互质的数的个数.
考虑n的素因子pi,则[1..r]中与pi不互质的数的个数是[r/pi].
然而,如果我们单纯将所有结果相加,会得到错误答案。有些数可能被统计多次(被好几个素因子整除)。所以,我们要运用容斥原理来解决。
我们可以用2^k的算法求出所有的pi组合,然后计算每种组合的pi乘积,通过容斥原理来对结果进行加减处理。
int solve(int r,int n){ int res = 0; vector p; for (int i = 2; i * i <= n; i ++){ if (n % i == 0){ p.push_back(i); while(n % i == 0){ n = n / i; } } } if (n > 1){ p.push_back(n); } for (int msk = 1; msk < (1 << p.size()); msk ++){ int mult = 1, bit = 0; for (int i = 0; i < p.size(); i ++){ if (msk & (1 << i)){ ++bit; mult *= p[i]; } } int cur = r / mult; if (bit % 2 == 1){ res += cur; } else res -= cur; } return r - res; }
回到此题中,求个数和求和是一样的,我们只需要考虑怎么处理第二个操作——因为这道题m给的很小,所以我们完全可以每次询问都枚举以前改变的情况,至此问题解决。注意一点就是同一个地方的数可能被改两次,所以用map映射处理比较好。
#include #include #include #include #include #include #include #include #include #include #include #include #define MID(x,y) ((x+y)>>1) using namespace std; typedef long long LL; //max long long == 9223372036854775807LL map m; inline LL gcd(LL a, LL b){ return b ? gcd(b, a % b) : a; } inline LL solve(int r,int n){ if (r == 0) return 0; LL rans = 0; rans = (LL)r * LL(r + 1) / 2; LL res = 0; /*找n的素因子*/ vector p; for (int i = 2; i * i <= n; i ++){ if (n % i == 0){ p.push_back(i); while(n % i == 0){ n = n / i; } } if (n == 1) break; } if (n > 1){ p.push_back(n); } /*找n的素因子*/ for (int msk = 1; msk < (1 << p.size()); msk ++){ int mult = 1; int bit = 0; for (int i = 0; i < p.size(); i ++){ if (msk & (1 << i)){ ++bit; mult *= p[i]; } } LL cur = r / mult; LL curans = 0; curans = (cur + 1) * cur / 2 * mult; if (bit % 2 == 1){ res += curans; } else res -= curans; } return rans - res; } int main(){ int t, n, M, pnum; scanf("%d",&t); while(t--){ pnum = 0; m.clear(); scanf("%d%d",&n,&M); for (int i = 0; i < M; i ++){ int num; scanf("%d",&num); if (num == 2){ int a,b; scanf("%d%d",&a, &b); m[a] = b; } else{ int x,y,pp; scanf("%d%d%d", &x, &y, &pp); LL ans = solve(y, pp) - solve(x - 1, pp); map :: iterator it; for (it = m.begin(); it != m.end(); it ++){ if (it->first >= x && it->first <= y){ if (gcd(it->first, pp) == 1){ ans -= it->first; } if (gcd(it->second, pp) == 1){ ans += it->second; } } } printf("%I64d\n",ans); } } } return 0; }
相关文章推荐
- HDU 4407 Sum(12年金华 容斥原理)
- hdu 4407 SUM(容斥原理)
- HDU 4407 Sum(容斥原理)
- HDU 4407 SUM 容斥原理
- HDU 4407 Sum【容斥原理】
- hdu 4407 Sum 容斥原理
- HDU-4407-Sum(容斥原理)
- HDU 4407 Sum 容斥原理
- hdu 4407 Sum (容斥原理)
- HDU 4407 Sum(12年金华网络赛-H题-容斥原理)
- HDU-4407-Sum(容斥原理)
- HDU 4407 Sum(容斥原理+质因数分解)
- HDU 4407 Sum(容斥原理+状态压缩)
- HDU 4407 Sum <容斥原理>
- HDU 4407 Sum ★(容斥原理)
- HDU 4407 - Sum(容斥原理)
- hdu 4407 Sum 容斥原理
- [容斥原理] hdu 4407 Sum
- HDU 4407 Sum(容斥原理)
- Hdu 4407 Sum(容斥原理)