HDU-4407-Sum(容斥原理)「建议收藏」

HDU-4407-Sum(容斥原理)

大家好,又见面了,我是全栈君。

Problem Description
XXX is puzzled with the question below: 

1, 2, 3, …, n (1<=n<=400000) are placed in a line. There are m (1<=m<=1000) operations of two kinds.

Operation 1: among the x-th number to the y-th number (inclusive), get the sum of the numbers which are co-prime with p( 1 <=p <= 400000).

Operation 2: change the x-th number to c( 1 <=c <= 400000).

For each operation, XXX will spend a lot of time to treat it. So he wants to ask you to help him.

 


Input
There are several test cases.

The first line in the input is an integer indicating the number of test cases.

For each case, the first line begins with two integers — the above mentioned n and m.

Each the following m lines contains an operation.

Operation 1 is in this format: “1 x y p”. 

Operation 2 is in this format: “2 x c”.
 


Output
For each operation 1, output a single integer in one line representing the result.

 


Sample Input
   
   
1 3 3 2 2 3 1 1 3 4 1 2 3 6

 


Sample Output
   
   
7 0

 


Source
#include <stdio.h>

int num,idx[1005],val[1005],prime[10],p[40000];

inline bool check(int x)
{
    int i;

    for(i=0;i<num;i++) if(x%prime[i]==0) return 0;

    return 1;
}

int main()
{
    int T,n,m,i,j,k,type,cnt,a,b,c,last,lxdcnt,lxdnum,l,r;
    long long ans;

    //把40W以内的素数预处理出来-----------------
    cnt=0;

    for(i=2;i<400000;i++)
    {
        for(j=2;j*j<=i;j++) if(i%j==0) break;

        if(j*j>i) p[cnt++]=i;
    }
    //------------------------------------------

    scanf("%d",&T);

    while(T--)
    {
        scanf("%d%d",&n,&m);

        cnt=0;

        for(i=1;i<=m;i++)
        {
            scanf("%d",&type);

            if(type==1)
            {
                scanf("%d%d%d",&a,&b,&c);

                ans=(long long)(a+b)*(b-a+1)/2;

                num=0;//质因数的个数

                //获取c的质因数-----------------
                last=0;

                while(c>1)
                {
                    if(c%p[last]==0)
                    {
                        prime[num++]=p[last];
                        c/=p[last];
                        while(c%p[last]==0) c/=p[last];
                    }

                    last++;
                }
                //-------------------------------

                //容斥原理-------------------------
                for(j=1;j<(1<<num);j++)
                {
                    lxdcnt=0;
                    lxdnum=1;

                    for(k=0;k<num;k++) if(j&(1<<k))
                    {
                        lxdcnt++;
                        lxdnum*=prime[k];
                    }


                    l=a/lxdnum*lxdnum;
                    if(l<a) l+=lxdnum;
                    r=b/lxdnum*lxdnum;
                    if(r<l) continue;

                    if(lxdcnt&1) ans-=(long long)(l+r)*((r-l)/lxdnum+1)/2;
                    else ans+=(long long)(l+r)*((r-l)/lxdnum+1)/2;
                }
                //-----------------------------------

                //对改动过的数字特殊推断-----------------------------------
                for(j=0;j<cnt;j++)
                {
                    if(idx[j]>=a && idx[j]<=b)
                    {
                        if(!check(idx[j]))
                        {
                            if(check(val[j])) ans+=val[j];
                        }
                        else
                        {
                            if(check(val[j])) ans=ans+val[j]-idx[j];
                            else ans-=idx[j];
                        }
                    }
                }
                //--------------------------------------------------------

                printf("%I64d\n",ans);
            }
            else
            {
                scanf("%d%d",&a,&b);

                for(j=0;j<cnt;j++) if(idx[j]==a)//注意,改动的点可能之前已被改动过
                {
                    val[j]=b;
                    break;
                }

                if(j==cnt)
                {
                    idx[cnt]=a;
                    val[cnt++]=b;
                }
            }
        }
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/115923.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 在python中用来安装第三方库的常用工具_什么库用于安装管理Python扩展包

    在python中用来安装第三方库的常用工具_什么库用于安装管理Python扩展包Python有一个全球社区:在这里,我们可以搜索Python第三方库的任何话题。PyPI的全称是Python包指数指Python包的指数。它是由PSF(Python软件基金会)和显示全球Python计算生态系统。我们需要学会使用PyPI的主要网站,搜索和发现我们使用第三方Python库和关心。例如,如果您正在开发一个blockchain-related程序,您需要使用Python的计算生态三个步…

    2022年10月14日
  • 加密狗android,Android系统加密狗的设计与实现

    加密狗android,Android系统加密狗的设计与实现摘要:随着IT产业的迅猛发展,软件作为IT产业中的一项重要产品,现在已经随着电脑进入千家万户,深入到用户生活中的每个地方。但是针对软件,有一个问题一直存在,那就是软件盗版的问题。随着软件影响范围的扩大,盗版软件带来的危害也是越发的严重。另外,智能手机也已经进入一个高速发展期,Android系统手机在智能手机市场中占据很大的一块份额。在这样的背景下,本文提出一种使用Android系统手机对软件进行…

  • k8s中实现pod自动扩缩容「建议收藏」

    k8s中实现pod自动扩缩容「建议收藏」如何在k8s中实现基于cpu、内存的pod自动扩缩容来应对非线性资源使用情况,以满足业务需求、节约资源。

  • 中文字体的种类_漂亮的中文字体

    中文字体的种类_漂亮的中文字体简单来分的话,大致可分为三类:1.古代字体:宋体,楷体等2.现代字体:各种黑体3.形变字体:各种美术字。按照衬线体来分的话:衬线体:宋体非衬线体:楷体,黑体。详情:宋体:宋体是一种衬

  • Web负载均衡的几种实现方式

    Web负载均衡的几种实现方式

  • eclipse没有server项,解决办法「建议收藏」

    eclipse集成Tomcat:   打开eclipse-窗口-首选项-服务器-运行时环境找到Tomcat然后添加。eclipse添加插件:   开发WEB项目时要集成Tomcat可以并不是所有的eclipse都有服务器选项,如果不幸你的正好没有,不要怕。首先我们打开eclipse-help-installnewsoftware然后在workwith中输…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号