kuangbin数论题单

没几道题,却做了很长时间。有几个很水的题,但大部分质量很高,尤其是最后做的三四个题,把我写吐了。 题单地址:[kuangbin带你飞]专题1-23

LightOJ 1370 Bi-shoe and Phi-shoe

筛法得到欧拉函数的值

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#define LOCAL0
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (int i=a; i<=(b); i++)
#define ROF(i, a, b) for (int i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
int euler[2000005];
void getEuler(int n){
	euler[1] = 1;
	for(int i=2; i<=n; i++){
		if(!euler[i]){
			for(int j=i; j<=n; j += i){
				if(!euler[j]){
					euler[j] = j;
				}
				euler[j] = euler[j]/i*(i-1);
			}
		}
	}
}
int mp[2000005];
int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
	getEuler(2000005);
	memset(mp, INF, sizeof(mp));
	FOR(i, 1, 2000005){
		if(euler[i]<=2000000){
			mp[euler[i]] = min(mp[euler[i]], i);
		}
	}
	ROF(i, 1500004, 1){
		mp[i] = min(mp[i], mp[i+1]);
	}
	mp[1] = 2;
	int T;
	cin >> T;
	FOR(tt, 1, T){
		ll ans = 0;
		int n;
		cin >> n;
		int t;
		FOR(i, 1, n){
			cin >>t;
			//cout << t << " " << mp[t] << endl;
			ans += mp[t];
		}
		printf("Case %d: %lld Xukha\n",tt,ans);
	}
	return 0;
}

LightOJ 1341 Aladdin and the Flying Carpet

网上很多代码对$1-b$进行循环,复杂度是不正确的。由于$a$的素因数最多只有$\log_{2}a$个。设$a=p_1^{k_1}p_1^{k_2}…p_1^{k_n}$,由基本不等式$k_1k_2..k_n<=(\frac{k_1+k_2…+k_n}{n})^2<=(\frac{\log_{2}a}{n})^2$,可知a的所有素因数个数的乘积不会太大,所以可以用$dfs$枚举$a$所有可能的因数。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#define LOCAL0
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (int i=a; i<=(b); i++)
#define ROF(i, a, b) for (int i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int MAXN=1000000;
// 素数筛选
int prime[MAXN+1];
void getPrime(){
	for(int i=2; i<=MAXN; i++){
		if(!prime[i]) prime[++prime[0]]=i;
		for(int j=1; j<=prime[0]&&prime[j]<=MAXN/i; j++){
			prime[prime[j]*i] = 1;
			if(i%prime[j]==0) break;
		}
	}
}
// 合数分解
ll factor[100][2];
int factCnt;
void getFactors(ll x){
	ll temp = x;
	factCnt = 0;
	for(int i=1; i<=prime[0] && prime[i]<=temp/prime[i]; i++){ //cout << i << " " << temp << endl;
		factor[factCnt][1] = 0;
		if(temp%prime[i]==0){
			factor[factCnt][0] = prime[i];
			while(temp%prime[i]==0){
				factor[factCnt][1]++;
				temp /= prime[i];
			}
			factCnt++;
		}
	}
	if(temp!=1){
		factor[factCnt][0] = temp;
		factor[factCnt++][1] = 1;
	}
}
ll a, b;
ll ans;
void dfs(ll now, ll tot){
	if(now==factCnt){
		if(tot*tot!=a && tot>=b && a/tot>=b) {
			ans++;
		}
		return;
	}
	ll temp = 1;
	FOR(i, 0, factor[now][1]){
		tot *= temp;
		dfs(now+1, tot);
		tot /= temp;
		temp *= factor[now][0];
	}
	return;
}
int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
	getPrime();
	int T;
	cin >> T;
	FOR(tt, 1, T){
		ans = 0;
		cin >> a >> b;
		getFactors(a);
		dfs(0, 1);
		ans /= 2;
		printf("Case %d: %d\n", tt, ans);
	}
	return 0;
}

LightOJ 1336 Sigma Function

将题目所给公式化简为$\sigma(n)=(1+p_1+..+p_1^{e_1})(1+p_2+..+p_2^{e_2})…(1+p_k+..+p_k^{e_k})$,如果要让$\sigma(n)$为奇数,由于当$p_k$为2时,$(1+p_k+..+p_k^{e_k})$一定为奇数,所以剩下的素因子的指数应该都是偶数,这样当2的指数也是偶数时,$n$是某个数的平方。当2的指数是奇数时,如果其余素因子的指数是偶数,应该有$n/2$是某个数的平方。综上$\sigma(n)$是奇数的条件就是$n$是某个数的平方或$n/2$是某个数的平方。这个题即输出$n-\sqrt{n}-\sqrt{n/2}$

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#define LOCAL0
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (int i=a; i<=(b); i++)
#define ROF(i, a, b) for (int i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int maxn=100000;
int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
	int t;
	cin >> t;
	FOR(i, 1, t){
		ll n;
		cin >> n;
		n -= (ll)sqrt(n)+(ll)sqrt(n/2);
		cout << "Case " << i << ": " << n << endl;
	}
	return 0;
}

LightOJ 1282 Leading and Trailing

后三位用快速幂对$n^k$模1000就可以了。计算前三位时把原数变形为$n^k=10^{\log_{10}a^k}=10^{k\log_{10}a}$,用$x,y$表示$k\log_{10}a$的整数部分与小数部分,可得$n^k=10^{x+y}=10^x*10^y$,则$n^k$的位数是由$10^x$决定的,各位数字是由$10^y$决定的,而$0\leq y<1$,所以$1\leq 10^y<10$,$10^y *100$的整数部分就是$n^k$的前三位。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#define LOCAL0
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (int i=a; i<=(b); i++)
#define ROF(i, a, b) for (int i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int maxn=100000;
//pow(x,n)%mod O(logn)
ll mod_pow(ll x,ll n,ll mod)
{
    ll res=1;
    while(n>0){
        if(n&1) res=res*x%mod;
        x=x*x%mod;
        n>>=1;
    }
    return res;
}
int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
	int T;
	cin >> T;
	FOR(tt, 1, T){
		ll n, k;
		cin >> n >> k;
		ll ans2 = mod_pow(n, k, 1000);
		double ans1 = k*log10(n);
		ans1 = fmod(ans1, 1);
		cout << "Case " << tt << ": " << (int)(pow(10, ans1)*100) << " ";
		cout << setw(3) << setfill('0') << ans2 << endl;
	}
	return 0;
}

LightOJ 1259 Goldbach`s Conjecture

把1e7以内的素数先筛出来,之后每个数枚举一下就行了。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#define LOCAL
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (int i=a; i<=(b); i++)
#define ROF(i, a, b) for (int i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int maxn=10000005;
//n以内素数个数
int prime[maxn];
bool is_prime[maxn+1];
int sieve(int n){
    int p=0;
    for(int i=0;i<=n;i++) is_prime[i]=true;
    is_prime[0]=is_prime[1]=false;
    for(int i=2;i<=n;i++){
        if(is_prime[i]){
            prime[p++]=i;
            for(int j=2*i;j<=n;j+=i) is_prime[j]=false;
        }
    }
    return p;
}
int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
	int T;
	cin >> T;
	int all = sieve(10000000);
	FOR(tt, 1, T){
		int x;
		cin >> x;
		int ans = 0;
		for(int i=0; i<all; i++){
			if(prime[i]>x/2) break;
			if(is_prime[x-prime[i]]) ans++;
		}
		cout << "Case " << tt << ": " << ans << endl;
	}
	return 0;
}

LightOJ 1245 Harmonic Number (II)

数论分块

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#define LOCAL
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (int i=a; i<=(b); i++)
#define ROF(i, a, b) for (int i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int maxn=10000005;
int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
	int T;
	cin >> T;
	FOR(tt, 1, T){
		ll n;
		cin >> n;
		ll ans = 0;
		for(ll l=1, r; l<=n; l=r+1){
			r = n/(n/l);
			ans += (r-l+1)*(n/l);
		}
		printf("Case %d: %lld\n", tt, ans);
	}
	return 0;
}

LightOJ 1236 Pairs Forming LCM

\[\begin{aligned} &设\,\,a=p_1^{k_{a1}}p_2^{k_{a2}}...p_s^{k_{as}},\,\,b=p_1^{k_{b1}}p_2^{k_{b2}}...p_s^{k_{bs}}\\ &有\,\,gcd(a,b)=p_1^{min(k_{a1},k_{b1})}p_2^{min(k_{a2},k_{b2})}...p_s^{min(k_{as},k_{bs})}\\ &\quad lcm(a,b)=p_1^{max(k_{a1},k_{b1})}p_2^{max(k_{a2},k_{b2})}...p_s^{max(k_{as},k_{bs})}\\ \end{aligned}\]

设$n=p_1^{k_1}p_2^{k_2}…p_m^{k_m}$,由上述式子不难得出$\forall 1\leq i,j\leq n$,使$lcm(i,j)=n$的方案数有$sum=(2k_1+1)(2k_2+1)…(2*k_m+1)$种,而本题要求$1\leq i\leq j\leq n$,所以方案数为$(sum+1)/2$(分子加一是考虑到$i=j$的情况)

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#define LOCAL
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (int i=a; i<=(b); i++)
#define ROF(i, a, b) for (int i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int maxn=10000005;
int prime[maxn+1];
void getPrime(){
	memset(prime, 0 ,sizeof(prime));
	for(int i=2; i<=maxn; i++){
		if(!prime[i]) prime[++prime[0]] = i;
		for(int j=1; j<=prime[0]&&prime[j]<=maxn/i; j++){
			prime[prime[j]*i] = 1;
			if(j%prime[j]==0) break;
		}
	}
}
ll factor[100][2];
int factCnt;
int getFactors(ll x){
	factCnt = 0;
	ll temp = x;
	for(int i=1; prime[i]<=temp/prime[i] && i<=prime[0]; i++){
		factor[factCnt][1] = 0;
		if(temp%prime[i]==0){
			factor[factCnt][0] = prime[i];
			while(temp%prime[i]==0){
				factor[factCnt][1]++;
				temp /= prime[i];
			}
			factCnt++;
		}
	}
	if(temp!=1){
		factor[factCnt][0] = temp;
		factor[factCnt++][1] = 1;
	}
	return factCnt;
}
int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
	getPrime();
	int T;
	cin >> T;
	FOR(tt, 1, T){
		ll n;
		cin >> n;
		ll ans = 1;
		getFactors(n);
		for(int i=0; i<factCnt; i++){
			ans *= 2*factor[i][1]+1;
		}
		ans = (ans+1)/2;
		printf("Case %d: %I64d\n", tt, ans);
	}
	return 0;
}

LightOJ 1234 Harmonic Number

直接暴力可以跑出来,但是数组开不到1e8,可以每50个数分一块,这样每次查询最多再跑49次就可以了。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#define LOCAL
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (int i=a; i<=(b); i++)
#define ROF(i, a, b) for (int i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int maxn=10000005;
double sum[20000005];
int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
	double temp;
	FOR(i, 1, 100000000){
		temp = 0;
		FOR(j, 1, 50){
			temp += 1/(double)i;
			i++;
		}
		i--;
		sum[i/50] = sum[i/50-1]+temp;
	}
	int T;
	cin >> T;
	FOR(tt, 1, T){
		ll n;
		cin >> n;
		double ans = sum[n/50];
		ROF(i, n, n-n%50+1) ans += 1/(double)i;
		printf("Case %d: %.10f\n", tt, ans);
	}
	return 0;
}

LightOJ 1220 Mysterious Bacteria

唯一分解定理后取指数项最小值即可。注意当n为负数时,答案一定为奇数,所以要将结果一直除二直到变为奇数。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#define LOCAL
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (int i=a; i<=(b); i++)
#define ROF(i, a, b) for (int i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int maxn=10000005;
int prime[maxn+1];
void getPrime(){
	memset(prime, 0 ,sizeof(prime));
	for(int i=2; i<=maxn; i++){
		if(!prime[i]) prime[++prime[0]] = i;
		for(int j=1; j<=prime[0]&&prime[j]<=maxn/i; j++){
			prime[prime[j]*i] = 1;
			if(j%prime[j]==0) break;
		}
	}
}
ll factor[100][2];
int factCnt;
int getFactors(ll x){
	factCnt = 0;
	ll temp = x;
	for(int i=1; prime[i]<=temp/prime[i] && i<=prime[0]; i++){
		factor[factCnt][1] = 0;
		if(temp%prime[i]==0){
			factor[factCnt][0] = prime[i];
			while(temp%prime[i]==0){
				factor[factCnt][1]++;
				temp /= prime[i];
			}
			factCnt++;
		}
	}
	if(temp!=1){
		factor[factCnt][0] = temp;
		factor[factCnt++][1] = 1;
	}
	return factCnt;
}
int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
	getPrime();
	int T;
	cin >> T;
	FOR(tt, 1, T){
		ll n;
		cin >> n;
		getFactors(abs(n));
		int ans = INF;
		FOR(i, 0, factCnt-1){
			ans = min(1ll*ans, factor[i][1]);
		}
		if(n<0) while(ans%2==0) ans /= 2;
		printf("Case %d: %d\n", tt, ans);
	}
	return 0;
}

LightOJ 1214 Large Division

高精度模板

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#define LOCAL
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (int i=a; i<=(b); i++)
#define ROF(i, a, b) for (int i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int maxn = 500;
struct bign{
    int d[maxn], len;

    void clean() { while(len > 1 && !d[len-1]) len--; }

    bign()          { memset(d, 0, sizeof(d)); len = 1; }
    bign(int num)   { *this = num; }
    bign(char* num) { *this = num; }
    bign operator = (const char* num){
        memset(d, 0, sizeof(d)); len = strlen(num);
        for(int i = 0; i < len; i++) d[i] = num[len-1-i] - '0';
        clean();
        return *this;
    }
    bign operator = (int num){
        char s[20]; sprintf(s, "%d", num);
        *this = s;
        return *this;
    }

    bign operator + (const bign& b){
        bign c = *this; int i;
        for (i = 0; i < b.len; i++){
            c.d[i] += b.d[i];
            if (c.d[i] > 9) c.d[i]%=10, c.d[i+1]++;
        }
        while (c.d[i] > 9) c.d[i++]%=10, c.d[i]++;
        c.len = max(len, b.len);
        if (c.d[i] && c.len <= i) c.len = i+1;
        return c;
    }
    bign operator - (const bign& b){
        bign c = *this; int i;
        for (i = 0; i < b.len; i++){
            c.d[i] -= b.d[i];
            if (c.d[i] < 0) c.d[i]+=10, c.d[i+1]--;
        }
        while (c.d[i] < 0) c.d[i++]+=10, c.d[i]--;
        c.clean();
        return c;
    }
    bign operator * (const bign& b)const{
        int i, j; bign c; c.len = len + b.len;
        for(j = 0; j < b.len; j++) for(i = 0; i < len; i++)
            c.d[i+j] += d[i] * b.d[j];
        for(i = 0; i < c.len-1; i++)
            c.d[i+1] += c.d[i]/10, c.d[i] %= 10;
        c.clean();
        return c;
    }
    bign operator / (const bign& b){
        int i, j;
        bign c = *this, a = 0;
        for (i = len - 1; i >= 0; i--)
        {
            a = a*10 + d[i];
            for (j = 0; j < 10; j++) if (a < b*(j+1)) break;
            c.d[i] = j;
            a = a - b*j;
        }
        c.clean();
        return c;
    }
    bign operator % (const bign& b){
        int i, j;
        bign a = 0;
        for (i = len - 1; i >= 0; i--)
        {
            a = a*10 + d[i];
            for (j = 0; j < 10; j++) if (a < b*(j+1)) break;
            a = a - b*j;
        }
        return a;
    }
    bign operator += (const bign& b){
        *this = *this + b;
        return *this;
    }

    bool operator <(const bign& b) const{
        if(len != b.len) return len < b.len;
        for(int i = len-1; i >= 0; i--)
            if(d[i] != b.d[i]) return d[i] < b.d[i];
        return false;
    }
    bool operator >(const bign& b) const{return b < *this;}
    bool operator<=(const bign& b) const{return !(b < *this);}
    bool operator>=(const bign& b) const{return !(*this < b);}
    bool operator!=(const bign& b) const{return b < *this || *this < b;}
    bool operator==(const bign& b) const{return !(b < *this) && !(b > *this);}

    string str() const{
        char s[maxn]={};
        for(int i = 0; i < len; i++) s[len-1-i] = d[i]+'0';
        return s;
    }
};
istream& operator >> (istream& in, bign& x)
{
    string s;
    in >> s;
    x = s.c_str();
    return in;
}
ostream& operator << (ostream& out, const bign& x)
{
    out << x.str();
    return out;
}
int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
	int T;
	cin >> T;
	FOR(tt, 1, T){
	    bign a,b;
		cin >> a >> b;
		if(a.d[a.len-1]<0) a.d[a.len-1] = 0, a.len--;
		if(b.d[b.len-1]<0) b.d[b.len-1] = 0, b.len--;
		if(a%b!=bign(0)) printf("Case %d: not divisible\n", tt);
		else printf("Case %d: divisible\n", tt);
	}
	return 0;
}

LightOJ 1213 Fantasy of a Summation

推式子,$res=kn^{k-1}sum$

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#define LOCAL
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (int i=a; i<=(b); i++)
#define ROF(i, a, b) for (int i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef long long ll;
// const ll mod = 1e9+7;
const int maxn = 500005;
int casecnt;
//pow(x,n)%mod O(logn)
ll mod_pow(ll x,ll n,ll mod)
{
    ll res=1;
    while(n>0){
        if(n&1) res=res*x%mod;
        x=x*x%mod;
        n>>=1;
    }
    return res;
}
int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
    int T;
    cin >> T;
    while(T--){
        ll n, k, mod, sum = 0;
        cin >> n >> k >> mod;
        FOR(i, 1, n){
            ll x;
            cin >> x;
            sum = (sum+x)%mod;
        }
        sum = mod_pow(n, k-1, mod)*k%mod*sum%mod;
        printf("Case %d: %lld\n", ++casecnt, sum);
    }
	return 0;
}

LightOJ 1197 Help Hanzo

区间素数模板

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#define LOCAL
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (int i=a; i<=(b); i++)
#define ROF(i, a, b) for (int i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int maxn = 1000005;
int casecnt;
int prime[maxn+1];
void getPrime(){
	memset(prime, 0 ,sizeof(prime));
	for(int i=2; i<=maxn; i++){
		if(!prime[i]) prime[++prime[0]] = i;
		for(int j=1; j<=prime[0]&&prime[j]<=maxn/i; j++){
			prime[prime[j]*i] = 1;
			if(j%prime[j]==0) break;
		}
	}
}
bool notprime[maxn];
int prime2[maxn];
void getPrime2(int l, int r){
    memset(notprime, false, sizeof(notprime));
    if(l<2) l = 2;
    for(int i=1; i<=prime[0]&&(ll)prime[i]*prime[i]<=r; i++){
        int s = l/prime[i]+(l%prime[i]>0);
        if(s==1) s=2;
        for(int j=s; (ll)j*prime[i]<=r; j++){
            if((ll)j*prime[i]>=l){
                notprime[j*prime[i]-l] = true;
            }
        } 
    }
    prime2[0] = 0;
    for(int i=0; i<=r-l; i++){
        if(!notprime[i]){
            prime2[++prime2[0]] = i+l;
        }
    }
}
int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
    getPrime();
    int T;
    cin >> T;
    while(T--){
        int l, r;
        cin >> l >> r;
        getPrime2(l, r);
        printf("Case %d: %d\n", ++casecnt, prime2[0]);
    }
	return 0;
}

LightOJ 1138 Trailing Zeroes (III)

$n!$后几位中0的个数其实就是$n!$因数中$5$的个数,不难推出对于一个确定的n,$n!$中后几位0的个数为$\frac{n}{5}+\frac{n}{5^2}+\frac{n}{5^3}+…$

二分答案即可

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#define LOCAL
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (int i=a; i<=(b); i++)
#define ROF(i, a, b) for (int i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int maxn = 1000005;
int casecnt;
ll fun(ll m){
    ll temp = 0;
    while(m){
        temp += m;
        m /= 5; 
    }
    return temp;
}
int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
    int T;
    cin >> T;
    while(T--){
        ll n;
        cin >> n;
        ll l = 0, r = 1e8;
        while(r-l>1){
            ll mid = (l+r)>>1;
            if(fun(mid)>n) r = mid;
            else l = mid;
        }
        cout << "Case " << ++casecnt << ": ";
        if(fun(l)==n) cout << 5*l << endl;
        else cout << "impossible\n";
    }
	return 0;
}

UVA 11426 GCD - Extreme (II)

\[\begin{aligned} &\sum_{i=1}^n\sum_{j=1}^ngcd(i,j)\\ =&\sum_{k=1}^nk\sum_{i=1}^n\sum_{j=1}^n[gcd(i,j)=k]\\ =&\sum_{k=1}^nk\sum_{i=1}^{n/k}\sum_{j=1}^{n/k}[gcd(i,j)=1]\\ =&\sum_{k=1}^nk\sum_{i=1}^{n/k}\sum_{j=1}^{n/k}\sum_{m|gcd(i,j)}\mu(m)\\ =&\sum_{k=1}^nk\sum_{m=1}^{n}\mu(m)*\frac{n}{km}*\frac{n}{km}\\ =&\sum_{D=1}^n\sum_{k|D}k*\mu(\frac{D}{m})*\frac{n}{D}*\frac{n}{D}\\ =&\sum_{D=1}^n\psi(D)*\frac{n}{D}*\frac{n}{D}\\ \end{aligned}\]

筛出欧拉函数后分块计算即可

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#define LOCAL
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (int i=a; i<=(b); i++)
#define ROF(i, a, b) for (int i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int maxn = 1000005;
// 筛法
int euler[4000005];
void getEuler(int n){
	euler[1] = 1;
	for(int i=2; i<=n; i++){
		if(!euler[i]){
			for(int j=i; j<=n; j += i){
				if(!euler[j]){
					euler[j] = j;
				}
				euler[j] = euler[j]/i*(i-1);
			}
		}
	}
}
ll sum[4000005];
int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
    getEuler(4000002);
    FOR(i, 1, 4000001) sum[i] = sum[i-1]+euler[i];
    ll n;
    while(cin >> n && n){
        ll ans = 0;
        for(int l=1, r; l<=n; l=r+1){
            r = n/(n/l);
            ans += (sum[r]-sum[l-1])*(n/l)*(n/l);
        }
        ans = (ans-n*(n+1)/2)/2;
        cout << ans << endl;
    }
	return 0;
}

POJ 1061 青蛙的约会

题目即求$x-y+p(m-n)=qL$,转化为$(m-n)x+Ly=y-x\quad(m>n)$形式用$exgcd$求出x的最小正整数解即可。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#define LOCAL
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <iomanip>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (int i=a; i<=(b); i++)
#define ROF(i, a, b) for (int i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int maxn=1005;
//返回值是gcd(a,b) x<=a,y<=b
ll extgcd(ll a,ll b,ll &x,ll &y)
{
    ll d=a;
    if(b!=0){
        d=extgcd(b,a%b,y,x);
        y-=(a/b)*x;
    }
    else{
        x=1;y=0;
    }
    return d;
}
int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
    ll x, y, m, n, l;
    cin >> x >> y >> m >> n >> l;
    ll p, q, d;
    if(m<n){
        swap(x, y);
        swap(m, n);
    }
    d = extgcd(m-n, l, p, q);
    if((y-x)%d) cout << "Impossible\n";
    else{
        p *= (y-x)/d;
        p %= l/d;
        p = (p+l/d)%(l/d);
        cout << p << endl;
    }    
    return 0;
}

POJ 2115 C Looooops

和上一个题差不多,注意直接使用$1«k$会造成溢出。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#define LOCAL
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <iomanip>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (int i=a; i<=(b); i++)
#define ROF(i, a, b) for (int i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int maxn=1005;
//返回值是gcd(a,b) x<=a,y<=b
ll extgcd(ll a,ll b,ll &x,ll &y)
{
    ll d=a;
    if(b!=0){
        d=extgcd(b,a%b,y,x);
        y-=(a/b)*x;
    }
    else{
        x=1;y=0;
    }
    return d;
}
int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
    ll a, b, c, k;
    while(cin >> a >> b >> c >> k){
        if(a+b+c+k==0) break;
        ll m = (1ll<<k);
        ll x, y;
        ll d = extgcd(c, m, x, y);
        if((b-a)%d){
            cout << "FOREVER\n";
        }
        else{
            x *= (b-a)/d;
            x %= m/d;
            x = (x+m/d)%(m/d);
            cout << x << endl;
        }
    }
    return 0;
}

HDU 2161 Primes

注意n小于等于零时结束输入

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#define LOCAL
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (int i=a; i<=(b); i++)
#define ROF(i, a, b) for (int i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
//n以内素数个数
const int maxn=1000000;
int prime[maxn];
bool is_prime[maxn+1];
int sieve(int n){
    int p=0;
    for(int i=0;i<=n;i++) is_prime[i]=true;
    is_prime[0]=is_prime[1]=false;
    for(int i=2;i<=n;i++){
        if(is_prime[i]){
            prime[p++]=i;
            for(int j=2*i;j<=n;j+=i) is_prime[j]=false;
        }
    }
    return p;
}

int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
    sieve(100000);
    is_prime[2] = false;
    int T = 0;
    int n;
    while(cin >> n && n>0){
        if(is_prime[n]) printf("%d: yes\n", ++T);
        else printf("%d: no\n", ++T);
    }
    return 0;
}

UVA 11827 Maximum GCD

数论题单的题考输入,就挺离谱的

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#define LOCAL
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (int i=a; i<=(b); i++)
#define ROF(i, a, b) for (int i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;

int gcd(int a, int b){
    return b==0? a: gcd(b, a%b);
}
char s[300000];
int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
    int T;
    cin >> T;
    getchar();
    while(T--){
        int ans = 0;
        int a[105];
        int m = 0;
        gets(s);
        for(int i=0; i<(int)strlen(s); i++){
            int sum = 0;
            if(isdigit(s[i])){
                while(isdigit(s[i])){
                    sum = sum*10 + s[i] - '0';
                    i++;
                }
                a[++m] = sum; 
            }
            
        }
        FOR(i, 1, m){
            FOR(j, 1, m){
                if(i!=j){
                    ans = max(ans, gcd(a[i], a[j]));
                }
            }
        }
        cout << ans << endl;
    }
    return 0;
}

SGU 106 The equation

扩欧求一组解后,根据其解集的形式,解出来两个$k$的范围,取个交集就可以了

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#define LOCAL
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (ll i=a; i<=(b); i++)
#define ROF(i, a, b) for (ll i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (ll)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
//返回值是gcd(a,b) x<=a,y<=b
ll extgcd(ll a,ll b,ll &x,ll &y)
{
    ll d=a;
    if(b!=0){
        d=extgcd(b,a%b,y,x);
        y-=(a/b)*x;
    }
    else{
        x=1;y=0;
    }
    return d;
}
int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
    ll a, b, c;
    ll l1, l2, r1, r2, L1, L2, R1, R2;
    L1 = L2 = -INF;
    R1 = R2 = INF;
    cin >> a >> b >> c;
    cin >> l1 >> r1 >> l2 >> r2;
    if(a==0 && b==0){
        if(c==0) cout << (r1-l1+1)*(r2-l2+1);
        else cout << 0;
        cout << endl;
        return 0;
    }
    ll x, y;
    c *= -1;
    ll d = extgcd(a, b, x, y);
    if(c%d){
        cout << 0;
        return 0;
    }
    x *= c/d;
    y *= c/d;
    b /= d;
    a /= d;
    if(b>0){
        L1 = ceil(1.0*(l1-x)/b);
        R1 = floor(1.0*(r1-x)/b);
    } 
    else if(b<0){
        R1 = floor(1.0*(l1-x)/b);
        L1 = ceil(1.0*(r1-x)/b);
    }
    if(a>0){
        L2 = ceil(1.0*(l2-y)/a);
        R2 = floor(1.0*(r2-y)/a);
    }
    else if(a<0){
        R2 = floor(1.0*(l2-y)/a);
        L2 = ceil(1.0*(r2-y)/a);
    }
    if(a){
        swap(L2, R2);
        L2 *= -1;
        R2 *= -1;
    }
    l1 = max(L1, L2);
    r1 = min(R1, R2);
    if(l1>r1) cout << 0 << endl;
    else cout << r1-l1+1 << endl;
    return 0;
}

POJ 2478 Farey Sequence

欧拉函数

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#define LOCAL
#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<stdio.h>
#include<utility>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (ll i=a; i<=(b); i++)
#define ROF(i, a, b) for (ll i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (ll)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
// 筛法
int euler[1000005];
ll sum[1000005];
void getEuler(int n){
	euler[1] = 1;
	for(int i=2; i<=n; i++){
		if(!euler[i]){
			for(int j=i; j<=n; j += i){
				if(!euler[j]){
					euler[j] = j;
				}
				euler[j] = euler[j]/i*(i-1);
			}
		}
	}
}
int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
    getEuler(1000005);
    FOR(i, 2, 1000000){
        sum[i] = sum[i-1]+euler[i];
    }
    int n;
    while(cin >> n && n){
        cout << sum[n] << endl;
    }
    return 0;
}

UVA 11752 The Super Powers

这个处理精度好恶心。。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#define LOCAL
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (ll i=a; i<=(b); i++)
#define ROF(i, a, b) for (ll i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (ll)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef unsigned long long ll;
const ll mod = 1e9+7;
//n以内素数个数
const int maxn=1000000;
int prime[maxn];
bool is_prime[maxn+1];
int sieve(int n){
    int p=0;
    for(int i=0;i<=n;i++) is_prime[i]=true;
    is_prime[0]=is_prime[1]=false;
    for(int i=2;i<=n;i++){
        if(is_prime[i]){
            prime[p++]=i;
            for(int j=2*i;j<=n;j+=i) is_prime[j]=false;
        }
    }
    return p;
}
vector<ll> ans;
map<ll, bool> ok;
int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
    sieve(1000005);
    ans.pb(1);
    ll mx = 1ll*18446744073709551615;
    for(ll i=2; i<=(1<<16); i++){
        ll base = i;
        for(int j=2; j<=100; j++){
            base *= i;
            if(is_prime[j]){
                if(base>mx/i) break;
                continue;
            }
            if(!ok[base]){
                ok[base] = true;
                ans.pb(base);
                
            }
            if(base>mx/i) break;
        }
    }
    sort(ALL(ans));
    for(auto x:ans) cout << x << endl;
    return 0;
}

UVA 10200 Prime Time

计算结果加上1e-8可以避免0.50000被计算成0.499999的问题

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#define LOCAL
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (ll i=a; i<=(b); i++)
#define ROF(i, a, b) for (ll i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (ll)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef unsigned long long ll;
const ll mod = 1e9+7;
bool judge(int x){
    for(int i=2; i*i<=x; i++){
        if(x%i==0) return false;
    }
    return true;
}
map<int, int> sum;
int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
    //sum[0] = 1;
    FOR(i, 0, 10000){
        sum[i] = sum[i-1]+judge(i*i+i+41);
    }
    int a, b;
    while(cin >> a >> b){
        printf("%.2f\n", (double)(sum[b]-sum[a-1])/(b-a+1)*100+1e-8);
    }
    return 0;
}

UVA 11916 Emoogle Grid

当一个格子在第一行或者上方不能染色时,该格子染色方案为$k$,否则为$k-1$。可以分别统计这两种格子的数目$num1,num2$,则答案为$r=k^{num1}*(k-1)^{num2}$

先令$m$为不能染色的格子行数的最大值$max$(也就是行数可能的最小值),计算一次结果,如果和$r$不一样,再假设行数为$max+1$,如果计算出来的答案$ans2$还和$r$不一样,之后每增加一行,就相当于多$n$个格子染$k-1$个颜色,有式子$r=ans2*((k-1)^{n})^{x}$,用$BSGS$算法求出来x,答案即为$max+x+1$

这题我一个人wa了一整页,好丢人。。。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#define LOCAL
#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<stdio.h>
#include<utility>
//#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (ll i=a; i<=(b); i++)
#define ROF(i, a, b) for (ll i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (ll)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef long long ll;
const ll mod = 1e8+7;
// 哈希BSGS O(sqrt(n)) a^x=b (mod n) a,n互质  
#define MOD 76543
ll hs[MOD], head[MOD], Next[MOD], id[MOD], top;
void insert(ll x, ll y){
    ll k = x%MOD;
    hs[top] = x, id[top] = y, Next[top] = head[k], head[k] = top++;
}
ll find(ll x){
    ll k = x%MOD;
    for(ll i=head[k]; i!=-1; i=Next[i]){
        if(hs[i]==x){
            return id[i];
        }
    }
    return -1;
}
ll BSGS(ll a, ll b, ll n){
    memset(head, -1, sizeof(head));
    top = 1;
    if(b==1) return 0;
    ll m = sqrt(n*1.0), j;
    ll x = 1, p = 1;
    for(ll i=0; i<m; i++, p=p*a%n) insert(p*b%n, i);
    for(ll i=m; ; i+=m){
        if((j=find(x=x*p%n))!=-1) return i-j;
        if(i>n) break;
    }
    return -1;
}
//pow(x,n)%mod O(logn)
ll mod_pow(ll x,ll n,ll mod)
{
    ll res=1;
    while(n>0){
        if(n&1) res=res*x%mod;
        x=x*x%mod;
        n>>=1;
    }
    return res;
}
int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
    ll T, _=0;
    cin >> T;
    while(T--){
        printf("Case %lld: ", ++_);
        ll n, k, b, r;
        cin >> n >> k >> b >> r;
        map<ll, map<ll, bool> > mp;
        vector<ll> x(b+1), y(b+1);
        ll mx = 1;
        FOR(i, 1, b){
            cin >> x[i] >> y[i];
            mp[x[i]][y[i]] = true;
            mx = max(mx, x[i]);
        }
        ll num1 = n, num2 = n*(mx-1);
        FOR(i, 1, b){
            if(x[i]==1){
                num1--;
            }
            else{
                num2--;
            }
            if(x[i]+1<=mx && !mp[x[i]+1][y[i]]) num2--, num1++;
        }
        ll base = mod_pow(k, num1, mod)*mod_pow(k-1, num2, mod)%mod;
        if(base==r){
            cout << mx << endl;
            continue;
        }
        num1 = n, num2 = n*mx;
        FOR(i, 1, b){
            if(x[i]==1){
                num1--;
            }
            else{
                num2--;
            }
            if(!mp[x[i]+1][y[i]]) num2--, num1++;
        }
        base = mod_pow(k, num1, mod)*mod_pow(k-1, num2, mod)%mod;
        ll ans = BSGS(mod_pow(k-1, n, mod), r*mod_pow(base, mod-2, mod)%mod, mod);
        cout << ans+mx+1 << endl;
    }
    return 0;
}

POJ 2116 Death to Binary?

将一个整数转化为$canonical\ Fibonacci\ representation$其实就是从大到小遍历斐波那契数,如果当前数字大于这个斐波那契数就减去它并且这一位表示为1否则表示为0。这道题一个数字最多就四十一位,所以从第四十一个斐波那契数开始遍历就行了。写两个函数,一个把斐波那契形式数字(字符串)转化为一个整数,一个把一个整数转化为斐波那契形式的字符串,之后的操作就很简单了

比较坑的是这个题$fib[0]=1,fib[1]=2$。还有当数字是0的时候,转化成字符串时要注意一下。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#define LOCAL
#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<stdio.h>
#include<utility>
//#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (ll i=a; i<=(b); i++)
#define ROF(i, a, b) for (ll i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (ll)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef long long ll;
const ll mod = 1e8+7;
int fib[45];
int toNum(string s){
    int ans = 0;
    FOR(i, 0, s.length()-1){
        ans += fib[i]*(s[s.length()-1-i]-'0');
    }
    return ans;
}
string toString(int x){
    string s = "";
    ROF(i, 43, 0){
        if(x>=fib[i]){
            x -= fib[i];
            s += "1";
        }
        else if(s!=""){
            s += "0";
        }
    }
    if(s=="") s = "0";
    return s;
}
int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
    fib[0] = 1;
    fib[1] = 2;
    FOR(i, 2, 43) fib[i] = fib[i-1]+fib[i-2];
    string x, y;
    while(cin >> x >> y){
        int a = toNum(x);
        int b = toNum(y);
        int c = a+b;
        string p = toString(a), q = toString(b), r = toString(c);
        int w = r.length();
        FOR(i, 1, r.length()-p.length()+2) cout << " ";
        cout << p << endl;
        cout << "+";
        FOR(i, 1, r.length()-q.length()+1) cout << " ";
        cout << q << endl;
        cout << "  ";
        FOR(i, 1, r.length()) cout << "-";
        cout << endl;
        cout << "  " << r << endl << endl;
    }
    return 0;
}

UVA 11754 Code Feat

要计算出结果有两种做法,一个是dfs枚举所有余数组合再用中国剩余定理求解,另一种是选定一个除数x,对于他对应的余数r,枚举$kx+r$并筛选出符合条件的解

这两种方法交上去亲测都会TLE,第一种方法适用于余数较少的情况,第二种方法适用于余数较多的情况,所以可以根据余数的数量来选择不同的方式求解

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#define LOCAL
#include<iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<stdio.h>
#include<utility>
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (ll i=a; i<=(b); i++)
#define ROF(i, a, b) for (ll i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (ll)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef long long ll;
const ll mod = 1e8+7;
ll c, s;
ll x[15], b[15], t[11], k[11][105], bst, fact;
vector<ll> ans;
set<ll> st[15];

void sol2(){
	sort(k[bst]+1, k[bst]+t[bst]+1);
	for(ll i=0; s; i++){
		FOR(j, 1, t[bst]){
			bool ok = true;
			ll tmp = k[bst][j]+x[bst]*i;
			if(tmp==0) continue;
			FOR(p, 1, c){
				if(!st[p].count(tmp%x[p])){
					ok = false;
					break;
				}
			}
			if(ok){
				cout << tmp << endl;
				s--;
				if(!s) return;
			}
		}
	}
}

ll extgcd(ll aa,ll bb,ll &xx,ll &yy)
{
    ll d=aa;
    if(bb!=0){
        d=extgcd(bb,aa%bb,yy,xx);
        yy-=(aa/bb)*xx;
    }
    else{
        xx=1;yy=0;
    }
    return d;
}

void CRT(){
	ll res=0;
	FOR(i, 1, c){
		ll m = fact/x[i];
		ll inv, y;
		extgcd(m, x[i], inv, y);
		inv = (inv%x[i]+x[i])%x[i];
		res = (res+inv*m*b[i]%fact)%fact; // 解集形式为ans+kt;
	}
	ans.pb((res+fact)%fact);
}

void dfs(ll now){
	if(now==c+1){
		CRT();
		return;
	}
	FOR(i, 1, t[now]){
		b[now] = k[now][i];
		dfs(now+1);
	}
	return;
}

void sol1(){
	dfs(1);
	sort(ALL(ans));
	for(ll i=0; s; i++){
		for(auto val: ans){
			if(val+i*fact>0){
				cout << val+i*fact << endl;
				s--;
				if(!s) return;
			}
		}
	}
}

int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
	while(cin >> c >> s && c && s){
		bst = 1;
		fact = 1;
		ans.clear();
		ll tot = 1;
		FOR(i, 1, c){
			st[i].clear();
			cin >> x[i];
			cin >> t[i];
			FOR(j, 1, t[i]) cin >> k[i][j], st[i].insert(k[i][j]);
			if(x[i]*t[bst]>t[i]*x[bst]) bst = i;
			tot *= t[i];
			fact *= x[i];
		}
		if(tot<=10000) sol1();
		else sol2();
		cout << endl;
	}
    return 0;
}

LightOJ 1356 Prime Independence

如果两个数满足$a=b\ast prime$则a与b素因子的个数必定为一奇一偶,所以可以按照每个数素因子个数的奇偶性建立二分图,存在$a=b\ast prime$关系的两个数之间连边,用$HK$算法求出最大独立集即可。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#define LOCAL
#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<stdio.h>
#include<utility>
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define debug(msg) cout << (msg) << endl
#define FOR(i, a, b) for (ll i=a; i<=(b); i++)
#define ROF(i, a, b) for (ll i=a; i>=(b); i--)
#define pb(x) push_back(x) 
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
#define sz(x) (ll)x.size()
#define JUDGE(x) if(x) cout << "Yes\n"; else cout << "No\n";
using namespace std;
typedef long long ll;
const ll mod = 1e8+7;
// 合数分解
const int MAXN=40000;
int prime[MAXN+1];
void getPrime(){
	memset(prime, 0 ,sizeof(prime));
	for(int i=2; i<=MAXN; i++){
		if(!prime[i]) prime[++prime[0]] = i;
		for(int j=1; j<=prime[0]&&prime[j]<=MAXN/i; j++){
			prime[prime[j]*i] = 1;
			if(j%prime[j]==0) break;
		}
	}
}
ll factor[100][2];
int factCnt, factNum;
int getFactors(ll x){
	factCnt = 0;
	factNum = 0;
	ll temp = x;
	for(int i=1; prime[i]<=temp/prime[i] && i<=prime[0]; i++){
		factor[factCnt][1] = 0;
		if(temp%prime[i]==0){
			factor[factCnt][0] = prime[i];
			while(temp%prime[i]==0){
				factor[factCnt][1]++;
				temp /= prime[i];
			}
			factCnt++;
		}
	}
	if(temp!=1){
		factor[factCnt][0] = temp;
		factor[factCnt++][1] = 1;
	}
	FOR(i, 0, factCnt-1) factNum += factor[i][1];
	return factCnt;
}
// HK二分图最大匹配 uN为左侧顶点数 G存单向边 顶点编号从0开始 O(sqrt(n)*m)
const int maxn = 40001;
vector<int> G[maxn];
int uN;
int Mx[maxn], My[maxn];
int dx[maxn], dy[maxn];
int dis;
bool used[maxn];
bool searchP(){
	queue<int> Q;
	dis = INF;
	memset(dx, -1, sizeof(dx));
	memset(dy, -1, sizeof(dy));
	for(int i=0; i<uN; i++){
		if(Mx[i]==-1){
			Q.push(i);
			dx[i] = 0;
		}
	}
	while(!Q.empty()){
		int u = Q.front();
		Q.pop();
		if(dx[u]>dis) break;
		int sz = G[u].size();
		for(int i=0; i<sz; i++){
			int v = G[u][i];
			if(dy[v]==-1){
				dy[v] = dx[u]+1;
				if(My[v]==-1) dis = dy[v];
				else{
					dx[My[v]] = dy[v]+1;
					Q.push(My[v]);
				}
			}
		}
	}
	return dis != INF;
}
bool dfs(int u){
	int sz = G[u].size();
	for(int i=0; i<sz; i++){
		int v = G[u][i];
		if(!used[v] && dy[v]==dx[u]+1){
			used[v] = true;
			if(My[v]!=-1 && dy[v]==dis) continue;
			if(My[v]==-1 || dfs(My[v])){
				My[v] = u;
				Mx[u] = v;
				return true;
			}
		}
	}
	return false;
}
int maxMatch(){
	int res = 0;
	memset(Mx, -1, sizeof(Mx));
	memset(My, -1, sizeof(My));
	while(searchP()){
		memset(used, false, sizeof(used));
		for(int i=0; i<uN; i++){
			if(Mx[i]==-1 && dfs(i)){
				res++;
			}
		}
	}
	return res;
}
int main()
{
	#ifdef LOCAL
		freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
	#endif
	getPrime();
	int T, _=0;
	cin >> T;
	while(T--){
		int n, cnt=0;
		uN = 0;
		cin >> n;
		vector<int> a(n+1);
		map<int, int> mp;
		vector<int> lft, ri;
		FOR(i, 1, n){
			scanf("%d", &a[i]);
		}
		FOR(i, 1, n){
			getFactors(a[i]);
			if(factNum%2){
				G[uN].clear();
				lft.pb(a[i]);
				mp[a[i]] = ++uN;
			}
			else{
				mp[a[i]] = ++cnt;
				ri.pb(a[i]);
			}
		}
		if(uN){
			FOR(i, 0, lft.size()-1){
				getFactors(lft[i]);
				FOR(j, 0, factCnt-1){
					if(mp[lft[i]/factor[j][0]]){
						G[i].pb(mp[lft[i]/factor[j][0]]);
					}
				}
			}
		}
		if(cnt){
			FOR(i, 0, ri.size()-1){
				getFactors(ri[i]);
				FOR(j, 0, factCnt-1){
					if(mp[ri[i]/factor[j][0]]){
						G[mp[ri[i]/factor[j][0]]-1].pb(i+1);
					}
				}
			}
		}
		printf("Case %d: %d\n", ++_, n-maxMatch());
	}
    return 0;
}