题意:有一个长度为n的数组,问能不能找一个子数组,使得他们的乘积不是一个平方数
思路:平方数*平方数=平方数,因此要找到一个乘积不是平方数的子数组,需要找一个不是平方的数。
代码:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
void solve ( )
{
int n;
scanf ( "%d" , & n) ;
int flag = 0 ;
for ( int i = 1 ; i <= n; i++ )
{
int num;
scanf ( "%d" , & num) ;
if ( ( int ) ( sqrt ( num) ) * ( int ) ( sqrt ( num) ) != num)
{
flag = 1 ;
}
}
if ( flag)
printf ( "YES\n" ) ;
else
printf ( "NO\n" ) ;
}
int main ( )
{
int t;
scanf ( "%d" , & t) ;
while ( t-- )
solve ( ) ;
return 0 ;
}
题意:给你n,k,计算出满足下面3个条件的长度为n的数组有多少个
1.所有元素的范围取值为0~2k-1
2.所有元素进行and操作之后为0
3.元素的和尽可能大
思路:每个数的范围从0~2k-1 这意味着这个数可以用k位2进制来表达的。有n个数,那就可以用n*k的二进制矩阵来表示所有的数。要使所有元素进行and操作之后为0,还要满足和尽可能大,这就是说每个二进制位有且仅有一位为0,最高位的n个数中只有一个为0,其他都为1,最低位的n个数中只有一个为0,其他为1。那么答案就为n^k
代码:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll mod = 1e9 + 7 ;
void solve ( )
{
int n, k;
scanf ( "%d%d" , & n, & k) ;
ll ans = 1ll ;
for ( int i = 1 ; i <= k; i++ ) {
ans = ans * n % mod;
}
printf ( "%lld\n" , ans) ;
}
int main ( )
{
int t;
scanf ( "%d" , & t) ;
while ( t-- )
solve ( ) ;
return 0 ;
}
题意:给你一个数n,请你在[1,2,…,n-1]中找一个最长的子序列,使得积模n等于1
思路:显然当无论n怎么取,1%n = 1.我们知道gcd(ai, n) = gcd(ai, n % ai),如n与ai不互质,那么乘积模n不可能为1,所以我们先取所有不与n互质的元素,当然n-1要特判,若前面的已经选中的数能被n模完为1就不要了。
代码:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main ( )
{
int n;
scanf ( "%d" , & n) ;
ll product = 1ll ;
queue< int > q;
for ( int i = 1 ; i < n - 1 ; i++ ) {
if ( __gcd ( i, n) == 1 ) {
q. push ( i) ;
product = product * i % n;
}
}
if ( product * ( n - 1 ) % n == 1ll )
q. push ( n- 1 ) ;
printf ( "%d\n" , q. size ( ) ) ;
while ( ! q. empty ( ) ) {
printf ( "%d%c" , q. front ( ) , " \n" [ q. size ( ) == 1 ] ) ;
q. pop ( ) ;
}
return 0 ;
}