HDU 4407 Sum ★(容斥原理)
题目链接: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乘积,通过容斥原理来对结果进行加减处理。
 
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         
 
举杯独醉,饮罢飞雪,茫然又一年岁。             ------AbandonZHANG
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号