URAL 1907. Coffee and Buns(数论推导+容斥原理)

1907. Coffee and Buns

Time limit: 1.0 second
Memory limit: 64 MB
Planet Ataraxia is known for its education centers. The people who are expected to take high social positions in future are brought up in conditions of continuous training and supervision from the early age. Each education center is a small town with all the necessary utilities. During the construction of a center, a square area is chosen which is divided into equal sections each sized 100 × 100 meters. In each of these sections they build one building, which would become residential or academic. The outer perimeter of the center is fenced.
After a successful military operation in the Andromeda nebula the active colonization of habitable planets has started. The need for people able to take command and lead people to the new worlds has increased. Therefore, two new education centers should be built on Ataraxia. Discussion about the details of the project in the local administration is already underway for many days. During this time it was decided that the first center will consist of  a 2 sections and that the second one will consist of no more than  n 2 sections. The situation is complicated because, according to requirements of the antimonopoly legislation, construction works must be performed by at least two different companies, each of them must build an equal number of buildings and an equal number of 100-meters segments of the fence.
You are responsible for resupplying the administration office. You understand that while they are discussing the pros and cons of each possible size of the second center a lot of buns and coffee will be consumed, and it's time to buy them. So you'd like to know how many different sizes of the second center will meet the requirements of antimonopoly legislation and, therefore, will be fully considered by the administration.

Input

The only line contains integers  a and  n (1 ≤  a ≤ 10 12; 1 ≤  n ≤ 10 18).

Output

Output an amount of different sizes of the second center meeting the requirements of antimonopoly legislation.

Sample

input output
3 6
4

Notes

In this example it is possible to build the second center sized 3 × 3 or 6 × 6, delegating the construction to three different companies, or to build it sized 1 × 1 or 5 × 5, delegating the construction to two different companies.
Problem Author: Ivan Burmistrov
Problem Source: Ural Championship 2012
Tags: none   (
hide tags for unsolved problems
)

大致题意:

输入 a n 判断 从 b = 1 ~ n 中 满足 gcd( ( a * a + b * b ) , 4 * a + 4 * b ) > 1 的个数。

a < 1e12 , n < 1e18

若 a b 奇偶性相同,显然满足。gcd是2的倍数。 

若a b  奇偶性不同,

开始推导:

因为 a * a + b * b 是奇数,

所以

gcd( a * a + b * b , 4 * a + 4 * b ) > 1 等价于

gcd( a * a + b * b , a + b ) > 1 等价于

根据整除性质,若存在 e > 1 ,满足 e | ( a + b ) , 那么 e | ( a + b ) ^ 2 反之亦然

则等价于

gcd( a * a + b * b , a * a + b * b + 2 * a * b ) > 1 等价于

gcd( 2 * a * a + 2 * b * b , a * a + b * b + 2 * a * b ) > 1等价于

gcd( a * a + b * b - 2 * a * b , a * a + b * b + 2 * a * b ) > 1 等价于

gcd( a - b , a + b ) > 1 等价于

gcd( 2 * a , a + b ) > 1

因为 a+b是奇数

等价于

gcd( a , a +b ) > 1等价于

gcd( a , b ) > 1

推导结束

下面对a分解质因数,找出n个数中不同奇偶性且满足gcd( a , b ) > 1的个数

最后加上 相同奇偶性的 个数 就是答案。


所以要求1~maxn中与a,gcd > 1 的个数,就是求1~maxn与某一个num不互素的个数,要用到容斥原理:

ll no_coprime(ll num,ll MAXN){//1~maxn与num不互素的个数
        ll ans = 0;
        vector<ll> fac;
        for(ll i = 2; i*i <= num; i++){ //分解因数
                if( num % i == 0){
                        fac.push_back(i);
                        while(num%i == 0) num /= i;
                }
        }
        if(num != 1) fac.push_back(num);
        int sz = SZ(fac);
        for(ll mask = 1 ; mask < (1LL<<sz); mask++){ //容斥过程,复杂度2^因数个数
                ll c = 0;
                ll tmp = 1;
                rep(i,sz) if( (1LL<<i)&mask){
                        c++;
                        tmp *= fac[i];
                }
                if(c&1) ans += MAXN/tmp;
                else ans -= MAXN/tmp;
        }
        return ans;
}



ac代码:

//Accepted 412	15 G++ 4.9 C++11 2092
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <cstdio>
#include <ctime>
#include <bitset>
#include <algorithm>
#define SZ(x) ((int)(x).size())
#define ALL(v) (v).begin(), (v).end()
#define foreach(i, v) for (__typeof((v).begin()) i = (v).begin(); i != (v).end(); ++ i)
#define reveach(i, v) for (__typeof((v).rbegin()) i = (v).rbegin(); i != (v).rend(); ++ i)
#define REP(i,n) for ( int i=1; i<=int(n); i++ )
#define rep(i,n) for ( int i=0; i<int(n); i++ )
using namespace std;
typedef long long ll;
#define X first
#define Y second
typedef pair<ll,ll> pii;

template <class T>
inline bool RD(T &ret) {
	char c; int sgn;
	if (c = getchar(), c == EOF) return 0;
	while (c != '-' && (c<'0' || c>'9')) c = getchar();
	sgn = (c == '-') ? -1 : 1;
	ret = (c == '-') ? 0 : (c - '0');
	while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
	ret *= sgn;
	return 1;
}
template <class T>
inline void PT(T x) {
	if (x < 0) {
		putchar('-');

		x = -x;
	}
	if (x > 9) pt(x / 10);
	putchar(x % 10 + '0');
}

ll a,n;

ll no_coprime(ll num,ll MAXN){
        ll ans = 0;
        vector<ll> fac;
        for(ll i = 2; i*i <= num; i++){ //分解因数
                if( num % i == 0){
                        fac.push_back(i);
                        while(num%i == 0) num /= i;
                }
        }
        if(num != 1) fac.push_back(num);
        int sz = SZ(fac);
        for(ll mask = 1 ; mask < (1LL<<sz); mask++){ //容斥过程,复杂度2^因数个数
                ll c = 0;
                ll tmp = 1;
                rep(i,sz) if( (1LL<<i)&mask){
                        c++;
                        tmp *= fac[i];
                }
                if(c&1) ans += MAXN/tmp;
                else ans -= MAXN/tmp;
        }
        return ans;
}

int main(){

        while(cin>>a>>n){
                ll ans = 0;
                if(a&1) ans += (n+1)/2, n /= 2;
                ans += no_coprime(a,n);
                printf("%lld\n",ans);
        }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值