UVA - 11246 - K-Multiple Free set(容斥原理)

题意:给定n(1 <= n <= 10^9)和k(1 <= k <= 100),从1~n中选尽量多的整数,使的任意两个整数之间都不是k倍的关系。

容斥原理,(例如n = 20,k = 3,答案为16个数(1,9,2,18,4,12,5,15,7,8,10,11,13,14,16,17,19,20))

一、n个数内共有n / k组数成为连续的k倍关系

       (有1、3、92、6、184、125、15781011131416171920,共n - n / k = 14个)

二、但是互为k ^ 2倍的关系同时也被删除了,所以要加回来

       (有918,共n - n / k + n / (k^2) = 16个)

三、若还存在k ^ 3倍的关系同时也被多加了,所以要再减去

四、若还存在k ^ 4倍的关系同时也被多加了,所以要加回来

……

综上,结果为n - n / k + n / (k ^ 2) - n / (k ^ 3) + n / (k ^ 4)……即应用容斥原理

(memset对于初始化10 ^ 9等的大数组非常慢,交的时候没有删去即TLE)

 

 1 #include<cstdio>  
 2 #include<cstring>  
 3 #include<cctype>  
 4 #include<cstdlib>  
 5 #include<cmath>  
 6 #include<iostream>  
 7 #include<sstream>  
 8 #include<iterator>  
 9 #include<algorithm>  
10 #include<string>  
11 #include<vector>  
12 #include<set>  
13 #include<map>  
14 #include<deque>  
15 #include<queue>  
16 #include<stack>  
17 #include<list>  
18 typedef long long ll;  
19 typedef unsigned long long llu;  
20 const int MAXN = 100 + 10;  
21 const int MAXT = 1000000000 + 10;  
22 const int INF = 0x7f7f7f7f;  
23 const double pi = acos(-1.0);  
24 const double EPS = 1e-6;  
25 using namespace std;  
26   
27 int T;  
28 ll n, k;  
29   
30 ll solve(){  
31     ll cur = 1, ans = n, tmp = n / k;  
32     while(tmp){  
33         ans -= cur * tmp;  
34         tmp /= k;  
35         cur = -cur;  
36     }  
37     return ans;  
38 }  
39   
40 int main(){  
41     scanf("%d", &T);  
42     while(T--){  
43         scanf("%lld%lld", &n, &k);  
44         printf("%lld\n", solve());  
45     }  
46     return 0;  
47 }  

 

转载于:https://www.cnblogs.com/tyty-TianTengtt/p/5995910.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值