#include<bits/stdc++.h>constint MAXN =1e5+10;typedeflonglong ll;
using namespace std;intmain(){int T;
cin >> T;while(T--){
ll n, k;
cin >> n >> k;if(n &1){for(int i =3;; i++){if(n % i ==0){
n += i;break;}}
n = n +(k -1)*2ll;}else{
n = n + k *2ll;}
cout << n << endl;}}
B.Orac and Models
题意:给你一个数列,让你从中选取一个严格上升的子序列,且对于子序列中的任意两个下标
i
,
j
(
i
<
j
)
i,j(i<j)
i,j(i<j),在原序列中的下标
p
i
,
p
j
(
p
i
<
p
j
)
p_i,p_j(p_i<p_j)
pi,pj(pi<pj),都有
p
j
p_j
pj整除
p
i
p_i
pi,问这样的子序列长度最长是多少?。
思路:定义
d
p
[
i
]
dp[i]
dp[i]为原序列前
i
i
i个数的最长答案,有转移:
d
p
[
j
]
=
m
a
x
{
d
p
[
i
]
+
1
}
i
f
(
i
∣
j
&
a
[
j
]
>
a
[
i
]
)
dp[j] = max\{dp[i] + 1\} \ if(i|j \ \&\ a[j]>a[i] )
dp[j]=max{dp[i]+1}if(i∣j&a[j]>a[i]),复杂度
O
(
n
l
o
g
(
n
)
)
O(nlog(n))
O(nlog(n))。ps:比赛的时候我dfs写的,又丑又长还会wa。。。。
#include<bits/stdc++.h>typedeflonglong ll;
using namespace std;constint MAXN =1e5+10;constint INF =0x3f3f3f3f;int a[MAXN];int dp[MAXN];intmain(){int T;
cin >> T;while(T--){int n;
cin >> n;for(int i =1; i <= n; i++){
cin >> a[i];
dp[i]=1;}int ret =1;for(int i =1; i <= n; i++){for(int j =2* i; j <= n; j += i){if(a[j]> a[i]){
dp[j]=max(dp[j], dp[i]+1);
ret =max(ret, dp[j]);}}}
cout << ret << endl;}}
C.Orac and LCM
题意:求任两个数的lcm的gcd
思路:设素数
p
p
p,假设最后的答案有
p
k
p^k
pk这样一个因子,那么
p
k
p^k
pk至少是原来的
n
−
1
n-1
n−1个数的因子。反证法可以证明。那么之后只要将所有的数进行因式分解,之后记录并统计一下各个素数出现的次数即可。
A.Orac and Factors题目:给你一个数每次递归地加上它自己的最小非1因数,问k次之后这个数是多少?思路:偶数一直加2,奇数先找到最小因数,加上后一定是个偶数,然后一直加2。#include <bits/stdc++.h>const int MAXN = 1e5 + 10;typedef long long ll;using namespace std; int main() { int T; cin >> T; while (T--) {