zoukankan      html  css  js  c++  java
  • 容斥原理与错排的结合

    今天好颓啊,上下午才打了两个容斥题


    容斥定理?不就是小学的韦恩图吗,加加减减的,这有什么大道理?

    然后我看到了今天的讲义!和题目!

    A - Co-prime

    Given a number N, you are asked to count the number of integers between A and B inclusive which are relatively prime to N.
    Two integers are said to be co-prime or relatively prime if they have no common positive divisors other than 1 or, equivalently, if their greatest common divisor is 1. The number 1 is relatively prime to every integer.
    Input
    The first line on input contains T (0 < T <= 100) the number of test cases, each of the next T lines contains three integers A, B, N where (1 <= A <= B <= 10 15) and (1 <=N <= 10 9).
    Output
    For each test case, print the number of integers between A and B inclusive which are relatively prime to N. Follow the output format below.
    Sample Input
    2
    1 10 2
    3 15 5
    Sample Output
    Case #1: 5
    Case #2: 10

    题意:求出a,b间与n不互质的数的个数 好简单的题意

    题解:要是直接让你求a,b之间的互质的数,好难啊,那求不互质的数?这可以有,先将n质因数分解,b除以n的质因数就可以得到1~b之间的与n不互质的数的一部分,但你会发现其中有些交集。

    比如10中有几个数与6互质,6的质因数为2,3。 10-10/3-10/2=2,,但其中的6这个数被多减了1次所以还要+10/6,这就要用到容斥定理了

    当有偶数种个质因数与n相同,就+,奇数个的就-,b-f[1]+f[2]+....+(-1)^m*f[m].

    var
    a,b,n,numm,ans,ans1,val,tot:int64;
    t,l,i,j:longint;
    num:array[0..100005]of int64;
    procedure get(x:int64);
    var i:longint; k:int64;
    begin
    k:=n;
    for i:=2 to trunc(sqrt(n))+1 do
    begin
    if k mod i=0 then begin inc(tot); num[tot]:=i; end;
    while k mod i=0 do k:=k div i;
    end;
    if k>1 then begin inc(tot);num[tot]:=k; end;
    end;
    begin
    readln(t);
    for l:=1 to t do
    begin
    fillchar(num,sizeof(num),0); tot:=0;
    readln(a,b,n);
    get(n);
    // for i:=1 to tot do writeln(num[i]);
    ans:=b;
    for i:=1 to (1<<tot)-1 do
    begin
    val:=1;numm:=0;
    for j:=0 to tot-1 do
    if (i and (1<<j))<>0 then
    begin
    inc(numm);
    val:=valnum[j+1];
    // writeln(j,' ',i);
    end;
    if numm mod 2=1 then ans:=ans- b div val else ans:=ans+b div val;
    end;
    ans1:=a-1;
    // writeln(ans);
    for i:=1 to (1<<tot)-1 do
    begin
    val:=1;numm:=0;
    for j:=0 to tot-1 do
    if ((1<<j) and i)<>0 then
    begin
    inc(numm);
    val:=val
    num[j+1];
    end;
    if numm mod 2=1 then ans1:=ans1- (a-1) div val else ans1:=ans1+(a-1) div val;
    end;
    writeln('Case #',l,': ',ans-ans1);
    end;
    end.

    NOIP2018 rp++
  • 相关阅读:
    那么这几天都是自己和工作上的事情比较零零散散
    在大家都返现的时候却有人什么都不奉献
    今天觉得自己好像比较紧张
    今天是下午有雨
    今天是星期五,上班已经三个礼拜了
    今天晚上控制电脑前,要提前开机
    其实对于家里的电脑就是硬盘不太好
    家里主要忙着建立房子
    今天装了一个RTI工具
    昨天已经开始讲业务的部分
  • 原文地址:https://www.cnblogs.com/brilliant107/p/9445010.html
Copyright © 2011-2022 走看看