您的位置:首页 > 其它

hdu4135-Co-prime & Codeforces 547C Mike and Foam (容斥原理)

2016-10-14 14:21 447 查看
hdu4135

求[L,R]范围内与N互质的数的个数。

分别求[1,L]和[1,R]和n互质的个数,求差。

利用容斥原理求解。

二进制枚举每一种质数的组合,奇加偶减。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N = 100005;

int fac
, cnt;

void factor(int n) {
cnt = 0;
int limit = sqrt(n);

for (int i = 2; i <= limit; ++i) {
if (n % i == 0) fac[cnt++] = i;
while (n % i == 0) n /= i;
}
if (n > 1) fac[cnt++] = n;
}

ll solve(ll x, int n) { //1~x中与n互质的数
ll ans = 0;
ll val;
int num;
//printf("cnt=%d\n", cnt);

int st = 1<<cnt;
for (int i = 1; i < st; ++i) {// 枚举所有情况,奇加偶减
val = 1;
num = 0;
for (int j = 0; j < cnt; ++j) {
if (i & (1<<j)) {
val *= fac[j];
num++;
}
}
//printf(">>%d %lld %d\n", i, val, num);
if (num & 1) ans += x/val;
else ans -= x/val;
}
return x - ans;
}

int main()
{
ll x, y;
int n;
int t, cas=0; cin >> t;
while (t--) {
cin >> x >> y >> n;
cout << "Case #" << ++cas << ": ";
factor(n);
cout << solve(y,n) - solve(x-1,n) << endl;
}

return 0;
}


Codeforces 547C Mike and Foam

差不多啦

求新加入的数和已经存在的数有多少是不互质的。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>

using namespace std;

const int N = 500005;
int a
, vis
, fac
, tfac
;
int n, m, q, tot;

void getfactor(int x, int fac[], int &cnt) {
int limit = sqrt(x);
cnt = 0;
for (int i = 2; i <= limit; ++i) {
if (x % i == 0) {
fac[cnt++] = i;
while (x % i == 0) x /= i;
}
}
if (x > 1) fac[cnt++] = x;
}

int add(int x, int d) {
int cnt;
getfactor(x, tfac, cnt);
int st = 1<<cnt;
int ans = 0;
for (int i = 1; i < st; ++i) {
int num = 0;
int tmp = 1;
for (int j = 0; j < cnt; ++j) {
if (i & (1<<j)) {
num++;
tmp *= tfac[j];
}
}
if (d == -1) fac[tmp]--;
if (num & 1) ans += fac[tmp];
else ans -= fac[tmp];
if (d == 1) fac[tmp]++;
}
if (d == -1) return -tot+ans;
else return tot-1-ans;
}

int main()
{
while (~scanf("%d%d", &n, &m)) {
memset(vis, 0, sizeof vis);
tot = 0;
for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
long long ans = 0 ,tmp;
while (m--) {
scanf("%d", &q);
if (vis[q]) vis[q] = 0, tot--, tmp = add(a[q], -1);
else vis[q] = 1, tot++, tmp = add(a[q], 1);
ans += tmp;
printf("%lld\n", ans);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: