• hdu 4407 Sum(容斥)


    http://acm.hdu.edu.cn/showproblem.php?

    pid=4407


    起初有n个数1~n。这里有m个操作。两种类型。操作1:求出[x,y]区间内与p互质的数的和。操作2:将第x位置的数变成y。对于每个询问,输出结果。


    由于仅仅有1000次操作,并且起初是有序的。那么对于第i个询问,我们先忽略i之前的全部的第2种操作。即觉得n个数为1~n,依据容斥原理求出[x,y]区间内与p互质的数之和。然后遍历i之前的操作2,对所求的答案进行调整就可以。wa了无数次,改了好久。是由于我忽略的一点。对x位置的数有可能进行多次改动。我们仅仅需考虑最后一次改动就可以。所以可用用map保存一下操作2。


    #include <stdio.h>
    #include <iostream>
    #include <map>
    #include <set>
    #include <bitset>
    #include <list>
    #include <stack>
    #include <vector>
    #include <math.h>
    #include <string.h>
    #include <queue>
    #include <string>
    #include <stdlib.h>
    #include <algorithm>
    #define LL __int64
    //#define LL long long
    #define eps 1e-9
    #define PI acos(-1.0)
    using namespace std;
    
    const int maxn = 400010;
    
    int n,m;
    bool flag[maxn];
    int prime[maxn];
    int fac[100];
    int facCnt;
    LL ans;
    map<int,int>M;
    
    int gcd(int a, int b)
    {
        if(b == 0)
            return a;
        return gcd(b,a%b);
    }
    
    void getPrime()
    {
        memset(flag,false,sizeof(flag));
        prime[0] = 0;
        for(int i = 2; i < maxn; i++)
        {
            if(flag[i] == false)
                prime[++prime[0]] = i;
            for(int j = 1; j <= prime[0]&&prime[j]*i < maxn; j++)
            {
                flag[prime[j]*i] = true;
                if(i % prime[j] == 0)
                    break;
            }
        }
    }
    
    void getFac(int num)
    {
        int tmp = num;
        facCnt = 0;
        for(int i = 1; i <= prime[0]&&prime[i]*prime[i] <= tmp; i++)
        {
            if(tmp % prime[i] == 0)
            {
                fac[facCnt++] = prime[i];
                while(tmp % prime[i] == 0)
                    tmp /= prime[i];
            }
            if(tmp == 1)
                break;
        }
        if(tmp > 1)
            fac[facCnt++] = tmp;
    }
    
    LL getSum(int t)
    {
        return ((1 + 1LL * t) * 1LL * t) >> 1;
    }
    
    //求【1,r】内与该数互质的数之和。
    LL cal(int r)
    {
        LL anw = getSum(r);
        LL tmp = 0;
    
        for(int i = 1; i < (1<<facCnt); i++)
        {
            LL mul = 1;
            int cnt = 0;
            for(int j = 0; j < facCnt; j++)
            {
                if(i&(1<<j))
                {
                    mul *= fac[j];
                    cnt++;
                }
            }
            if(cnt&1)
                tmp += mul * getSum((LL)r/mul);
            else tmp -= mul * getSum((LL)r/mul);
        }
        return anw - tmp;
    }
    
    int main()
    {
        getPrime();
        int test;
        scanf("%d",&test);
        while(test--)
        {
            M.clear();
            int op,x,y,z;
    
            scanf("%d %d",&n,&m);
            for(int i = 1; i <= m; i++)
            {
                scanf("%d",&op);
                if(op == 1)
                {
                    scanf("%d %d %d",&x,&y,&z);
                    getFac(z);
                    ans = cal(y) - cal(x-1);
    
                    //printf("ans : %I64d
    ",ans);
    
                    map<int,int>::iterator it;
                    for(it = M.begin(); it != M.end(); it++)
                    {
                       if(it->first >= x && it->first <= y)
                       {
                            if(gcd(z,it->first) == 1)
                                ans -= it->first;
                            if(gcd(z,it->second) == 1)
                                ans += it->second;
                       }
                    }
                    printf("%I64d
    ",ans);
                }
                else
                {
                    scanf("%d %d",&x,&y);
                    M[x] = y;
                }
            }
        }
        return 0;
    }
    
    


  • 相关阅读:
    gcc各个版本下载
    加减法运算解决乘除法
    蚂蚁碰撞的概率
    ns2.34移植leach协议
    ubantu16.04安装ns2.34 错误
    ubantu安全卸载火狐浏览器
    post和get的区别
    docker加速配置阿里云镜像
    重装系统后,会因为本机保存的公匙不对报错
    集合 set
  • 原文地址:https://www.cnblogs.com/cynchanpin/p/6946745.html
Copyright © 2020-2023  润新知