k
=
1
,
2
,
3
,
4
,
5
k = 1,2,3,4,5
k=1,2,3,4,5,我们分别选的是
n
0
n ^ 0
n0,
n
1
n ^ 1
n1,
n
0
+
n
1
n ^ 0 + n ^ 1
n0+n1,
n
2
n ^ 2
n2,
n
0
+
n
2
n ^ 0 + n ^ 2
n0+n2。
然后我们就可以得出一个规律,那就是我们把
k
k
k变成二进制,如果当前二进制位为
1
1
1的话我们就加上
n
x
n ^ x
nx,
x
x
x是指该二进制位是第几位,然后注意longlong 和 取模即可。
代码
#include<bits/stdc++.h>#definelllonglongusingnamespace std;const ll mod =1e9+7;intmain(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);int t;
cin >> t;while(t--){
ll n, k;
cin >> n >> k;
ll ans =0;
ll p =1;for(int j =0; j <=31; j++){if(k &(1<< j)){
ans =(ans + p)% mod;}
p *= n;
p %= mod;}
cout << ans << endl;}return0;}
C. Make Them Equal
思路分析
这题也挺简单的,很容易想到最多需要两次操作,因为
1
<
=
x
<
=
n
1 <= x <= n
1<=x<=n,所以我们只要选
n
−
1
n - 1
n−1和
n
n
n必然能完成任务,因为选
n
n
n就把除
n
n
n这个位置以外的位置全部弄好了,然后就是
n
−
1
n-1
n−1必然不会被
n
n
n整除。
所以我们就要思考一下只要一次操作和0次操作的情况。
看下题目要求的时间,试试暴力(乌鱼子,我还想是不是质因数分解然后拿最小的质因数和
n
n
n比大小,不知道有同学这样试了没)。
暴力的时候注意一下,
o
(
n
2
)
o(n^2)
o(n2)是过不了这题的,所以我们以
x
x
x为第一层循环,这样能优化时间。因为这样的话我们下标就不用一个一个遍历,只需要加上
x
x
x即可。
代码
#include<bits/stdc++.h>#definelllonglongusingnamespace std;intmain(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);int t;
cin >> t;while(t--){
vector<int> ans;bool ok =true;int n;
cin >> n;char ch;
cin >> ch;
string s;
cin >> s;for(int i =0; i < s.size(); i++){if(s[i]!= ch){
ok =false;}}if(!ok){for(int i =1; i <= n; i++){
ok =true;for(int j = i; j <= n; j++){
ok &=(s[j -1]== ch);
j += i -1;}if(ok){
ans.push_back(i);break;}}}if(!ok){
ans.push_back(n);
ans.push_back(n -1);}
cout << ans.size()<< endl;for(int x : ans){
cout << x <<' ';}
cout << endl;}return0;}
D. The Number of Imposters
思路分析
我们可以把
i
m
p
o
s
t
e
r
imposter
imposter表示为相反关系,即如果我认为他说的是假话,那么如果我说的是真的,他就是假的,我如果是假的,他就是真的,
c
r
e
w
m
a
t
e
crewmate
crewmate刚好相反。
#include<bits/stdc++.h>usingnamespace std;#definelllonglongconst ll mod =1e9+7;
ll qpow(ll a, ll b){
ll ans =1;while(b){if(b &1)
ans = ans * a % mod;
a = a * a % mod;
b >>=1;}return ans;}intmain(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);int k;
cin >> k;
ll ans =qpow(4,(1ll<< k)-2)% mod *6% mod;
cout << ans << endl;return0;}