k k k次操作,给 n n n每次加上其的最小因数( n n n会改变), k k k次操作之后,输出 n n n
如果 n n n为奇数,那么其最小因数肯定为奇数,相加之后的 n n n即为偶数,而偶数的最小因子为2,之后 n n n一直为偶数
因此只要在一开是 f o r for for一遍找出最小因子,加上后,加上 ( k − 1 ) ∗ 2 (k-1)*2 (k−1)∗2即可
#include
using namespace std;
typedef long long ll;
ll t,n,k;
int main() {
scanf("%lld",&t);
while(t--) {
scanf("%lld%lld",&n,&k);
for(int i=2; i<=n; i++)
if(n%i==0) {
n+=i;
break;
}
n+=(k-1)*2;
printf("%lld\n",n);
}
}
长度为 n n n的序列,问取出最长的子序列满足以下条件,相邻标号,右边的序号是左边的倍数(在原序列中),且值为递增。
#include
using namespace std;
int t,n;
int a[100100],f[100100];//f数组表示以当前位置的数为开头的最长子序列
int dfs(int pos) {
//system("pause");
if(f[pos]) return f[pos];//搜过就不搜了
f[pos]=1;
for(int i=2; i<=n; i++) {
if(pos*i>n) break;
if(a[pos*i]>a[pos]) {//吐槽:一开始在这里,一直写i一直错....
f[pos]=max(f[pos],dfs(pos*i)+1);
}
}
return f[pos];
}
int main() {
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
for(int i=1; i<=n; i++)
if(!f[i]) f[i]=dfs(i);
int ans=0;
for(int i=1; i<=n; i++) {
ans=max(ans,f[i]);
f[i]=0;
}
printf("%d\n",ans);
}
}
n n n个数,分别为a1,a2…an,构造一个 b b b序列,其中元素为:lcm(a1,a2),lcm(a1,a3)…lcm(a1,an),lcm(a2,an)…,lcm(an-1,an),问这些数的最大公约数是什么?
最后一秒钟没交上去…第二天就A了…
第一种方法: g c d ( l c m ( a , b ) , l c m ( a , c ) ) = a ∗ g c d ( b , c ) / g c d ( a , b , c ) gcd(lcm(a,b),lcm(a,c))=a*gcd(b,c)/gcd(a,b,c) gcd(lcm(a,b),lcm(a,c))=a∗gcd(b,c)/gcd(a,b,c)
什么要证明?对不起,不会ing…留坑
填坑: g c d ( l c m ( a , b ) , l c m ( a , c ) ) = a ∗ g c d ( b , c ) / g c d ( a , b , c ) gcd(lcm(a,b),lcm(a,c))=a*gcd(b,c)/gcd(a,b,c) gcd(lcm(a,b),lcm(a,c))=a∗gcd(b,c)/gcd(a,b,c)与 g c d ( l c m ( a , b ) , l c m ( a , c ) ) = l c m ( a , g c d ( b , c ) ) gcd(lcm(a,b),lcm(a,c))=lcm(a,gcd(b,c)) gcd(lcm(a,b),lcm(a,c))=lcm(a,gcd(b,c))等价
1.将 l c m ( x , y ) lcm(x,y) lcm(x,y)看作x和y质因子的并集, g c d ( x , y ) gcd(x,y) gcd(x,y)看作x和y质因子的交集
2. 左 式 = ( A ⋃ B ) ⋂ ( A ⋃ C ) 左式=(A \bigcup B) \bigcap (A \bigcup C) 左式=(A⋃B)⋂(A⋃C)
3. 右 式 = A ⋃ ( B ⋂ C ) 右式=A \bigcup (B \bigcap C) 右式=A⋃(B⋂C)
4.用点集合知识就能证明 左 式 = 右 式 左式=右式 左式=右式
其余做法:
#include
using namespace std;
typedef long long ll;
ll n;
ll a[100100], d[100100], b[100100];
ll Gcd(ll a, ll b) {
if(b == 0) return a;
else return Gcd(b, a%b);
}
int main() {
scanf("%lld", & n);
for(int i = 1; i <= n; i++) scanf("%d", & a[i]);
d[n] = a[n];//d[i]数组计算a[n]~a[i]的最大公约数
for(int i = n-1; i >= 1; i--) d[i] = Gcd(d[i+1], a[i]);
for(int i = 1; i <= n; i++) b[i] = a[i] * d[i+1] / d[i];
ll ans = b[n];
for(int i = 1; i <= n-1; i++) ans = Gcd(ans, b[i]);
cout << ans <<endl;
}
一个数组里一段数可以都变成他的中位数,问整个序列中的数能不能都变成 k k k。可以变化很多次。(偷懒ing)
#include
using namespace std;
int t, n, k, tag1, tag2;
int a[100100];
int main() {
scanf("%d", & t);
while(t--) {
scanf("%d%d", & n, & k);
for(int i = 1; i <= n; i++) scanf("%d", & a[i]);
tag1 = tag2 = 0;//tag1代表是否满足条件1,tag2代表是否满足条件2
for(int i = 1; i <= n; i++) {
if(a[i] == k) tag1 = 1;
if(a[i] >= k && a[i + 1] >= k || a[i - 1] >= k && a[i + 1] >= k) tag2 = 1;
}
if(tag1 && tag2 || n == 1 && a[1] == k) printf("YES\n");
//注意特判n = 1的情况
else printf("NO\n");
for(int i = 1; i <= n; i++) a[i] = 0; //初始化
}
return 0;
}