不同幂次的和,不就是求出
n
n
n 进制下的第
k
k
k 小的数是多少嘛! 直接把
k
k
k 拆成二进制的数字,这一位为
1
1
1,那么这个数就加上
n
c
n^c
nc 即可
代码
时间复杂度:
O
(
T
log
k
)
O(T\log k)
O(Tlogk)
#include<bits/stdc++.h>
using namespace std;voidshow(){std::cerr << endl;}template<typename T,typename... Args>voidshow(T x,Args... args){std::cerr <<"[ "<< x <<" ] , ";show(args...);}typedeflonglong ll;constint MAX =1e5+50;constint MOD =1e9+7;intmain(){int T;cin >> T;while(T--){int n,k;
cin >> n >> k;
queue<int>S;while(k){if(k&1)S.push(1);else S.push(0);
k >>=1;}
ll tmp =1;
ll ans =0;while(!S.empty()){if(S.front()==1)ans =(ans + tmp)% MOD;
tmp = tmp * n % MOD;
S.pop();}
cout << ans << endl;}return0;}
C. Make Them Equal *1200
题意
给你一个长度为
n
n
n 的字符串
s
[
1
]
.
.
.
s
[
n
]
s[1]...s[n]
s[1]...s[n],给你一个目标字符
c
c
c 一次操作,选择一个位置
i
i
i,然后对于所有的位置
j
j
j,满足
i
∤
j
i\not|\ j
i∣j,让
s
[
j
]
=
c
s[j]=c
s[j]=c 问你最少操作次数,和相应操作的位置,让这个字符串的每一个位置都变成
c
c
c
这里
2
k
2^k
2k 并不会爆
l
l
ll
ll,可以直接去算。 若你要取模的话,根据欧拉降幂,请取模
φ
(
1
e
9
+
7
)
=
1
e
9
+
6
\varphi(1e9+7)=1e9+6
φ(1e9+7)=1e9+6
代码
时间复杂度:
O
(
l
o
g
k
)
O(log k)
O(logk)
#include<bits/stdc++.h>
using namespace std;voidshow(){std::cerr << endl;}template<typename T,typename... Args>voidshow(T x,Args... args){std::cerr <<"[ "<< x <<" ] , ";show(args...);}typedeflonglong ll;constint MAX =2e5+50;constint MOD =1e9+7;
ll qpow(ll a,ll n){/* */ll res =1LL;while(n){if(n&1)res=res*a%MOD;a=a*a%MOD;n>>=1;}return res;}
ll qpow(ll a,ll n,ll p){a%=p;ll res =1LL;while(n){if(n&1)res=res*a%p;a=a*a%p;n>>=1;}return res;}
ll npow(ll a,ll n){/* */ll res =1LL;while(n){if(n&1)res=res*a;a=a*a;n>>=1;if(res<0||a<0)return0;}return res;}
ll inv(ll a){/* */returnqpow(a,MOD-2);}
ll inv(ll a,ll p){returnqpow(a,p-2,p);}intmain(){
ll k;
cin >> k;
ll tmp =(qpow(2,k,MOD-1)-2+(MOD-1))%(MOD-1);
cout <<1LL*6*qpow(4,tmp)% MOD;return0;}
E2. Rubik’s Cube Coloring (hard version) *2300
题意
其他条件和上题的条件相同 这里已知
n
n
n 个点,给定每个点的编号和颜色 求这个树的合法染色的方案数取模
1
e
9
+
7
1e9+7
1e9+7
1
≤
n
≤
min
(
2
k
−
1
,
2000
)
1\le n\le \min(2^k-1,2000)
1≤n≤min(2k−1,2000)
思路
根据上面条件的分析,若没有已知颜色的点,仍然儿子节点的方案数是
4
4
4 我们把每个已知的点,这个点到根节点的所有点,边全部拉出来,变成一个新的树
T
T
T 首先有一个结论:设
f
(
T
)
f(T)
f(T) 表示这个树的合法染色的方案数,
s
z
(
T
)
sz(T)
sz(T) 表示这个树的点的个数 那么最终的答案为:
f
(
T
)
×
4
2
k
−
1
−
s
z
(
T
)
f(T)\times 4^{2^k-1-sz(T)}
f(T)×42k−1−sz(T) 因为那些不在
T
T
T 上的结点,都有
4
4
4 种可选的方案。
接下来我们考虑怎么去求
f
(
T
)
f(T)
f(T) 注意到,我们对于每一个题目给定的结点,最多拉出
k
k
k 个节点到
T
T
T 上,所以
O
(
s
z
(
T
)
)
=
n
k
O(sz(T))=nk
O(sz(T))=nk 考虑到固定一些颜色求方案数,我们可以写一个
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j] 表示
i
i
i 节点选择颜色
j
j
j ,在
T
T
T 中以它为根,它的子树的合法染色方案数为
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j] 那么我们可以很简单地去进行转移。
还有一个是如何建树的问题。首先判断这个节点是第几层,是很简单的,节点编号减去
1
,
2
,
4
,
⋯
1,2,4,\cdots
1,2,4,⋯ ,直到再减就变负了为止,就能算出正确的层数,也能知道这个节点是这一层的从左往右数第几个,设为第
n
u
m
num
num 个(
0
−
i
n
d
e
x
0-index
0−index) 然后想一下,这个
n
u
m
num
num 与从根节点,每次往左还是往右走,手算一下
n
u
m
=
0
,
L
L
L
num=0,LLL
num=0,LLL
n
u
m
=
1
,
L
L
R
num=1,LLR
num=1,LLR
n
u
m
=
2
,
L
R
L
num=2,LRL
num=2,LRL
n
u
m
=
3
,
L
R
R
num=3,LRR
num=3,LRR … 然后发现是和这个数的二进制有关的,随便搞搞就可以了
给你
s
,
n
,
k
s,n,k
s,n,k 一个合法序列,满足
(
∑
i
=
1
n
a
[
i
]
)
=
s
,
a
[
i
]
∈
Z
+
(\sum_{i=1}^n a[i])=s,a[i]\in Z^+
(∑i=1na[i])=s,a[i]∈Z+ 问你是否对于所有的合法序列,都有某一个连续子段,满足这个子段的和为
k
k
k
样例组数
≤
1
0
5
\le 10^5
≤105
1
≤
s
,
n
,
k
≤
1
0
18
,
n
≤
s
1\le s,n,k\le 10^{18},n\le s
1≤s,n,k≤1018,n≤s
思路
首先容易得到
s
=
k
s=k
s=k 一定是
Y
E
S
YES
YES ,
s
<
k
s<k
s<k 一定是
N
O
NO
NO 所以我们下文都考虑
s
≥
k
s\ge k
s≥k
s
t
d
std
std 用到前缀和和抽屉原理的相关内容,我这里说明一个更好懂的做法。
首先,若
s
s
s 最小,自然
a
[
1
]
=
a
[
2
]
=
⋯
=
a
[
n
]
=
1
a[1]=a[2]=\cdots =a[n]=1
a[1]=a[2]=⋯=a[n]=1,此时自然可以选择一个长度为
k
k
k 的子段,字段和就是
k
k
k 了。
那么,若
s
s
s 非常大,自然一定有一个组合满足
a
[
1
]
,
a
[
2
]
,
⋯
a
[
n
]
>
k
a[1],a[2],\cdots a[n]>k
a[1],a[2],⋯a[n]>k,自然是
N
O
NO
NO
然后,我们感觉当
s
>
=
s>=
s>= 某个值,就是
N
O
NO
NO,否则就是
Y
E
S
YES
YES 的感觉。
那么我们进行 极限构造,即用最小的
s
s
s 构造出一种不符合要求的组合,就是这个分界线了。 我们怎么去构造呢?首先我想用很多个
1
1
1 填充,因为要求每个位置的值都是正整数。 但是如果有连续的
k
k
k 个
1
1
1,那就合法了,不行,所以我们每
k
−
1
k-1
k−1 个数,就用一个数字间隔开。 这个间隔的数字容易得到,至少是
k
+
1
k+1
k+1 所以我们构造出来的数组张这样:
[
1
,
1
,
1
,
⋯
,
1
k
−
1
个
1
,
(
k
+
1
)
,
1
,
1
,
1
,
⋯
,
1
k
−
1
个
1
,
(
k
+
1
)
,
1
,
⋯
,
1
]
[\underset{k-1个1}{1,1,1,\cdots,1},(k+1),\underset{k-1个1}{1,1,1,\cdots,1},(k+1),1,\cdots,1]
[k−1个11,1,1,⋯,1,(k+1),k−1个11,1,1,⋯,1,(k+1),1,⋯,1] 那么,这个分界线容易得到,就是
⌊
n
k
⌋
×
(
k
+
1
)
+
(
n
−
⌊
n
k
⌋
)
\lfloor \frac{n}{k} \rfloor \times (k+1) + (n - \lfloor \frac{n}{k} \rfloor)
⌊kn⌋×(k+1)+(n−⌊kn⌋)
容易得到,这个就是最少数目的
s
s
s,且非法的构造了。 所以我们判断是否
s
≥
这
个
玩
意
儿
s\ge 这个玩意儿
s≥这个玩意儿,那就是
N
O
NO
NO 了。
代码
时间复杂度:
O
(
T
)
O(T)
O(T)
#include<bits/stdc++.h>
using namespace std;voidshow(){std::cerr << endl;}template<typename T,typename... Args>voidshow(T x,Args... args){std::cerr <<"[ "<< x <<" ] , ";show(args...);}typedeflonglong ll;constint MAX =3e5+50;constint MOD =1e9+7;
ll qpow(ll a,ll n){/* */ll res =1LL;while(n){if(n&1)res=res*a%MOD;a=a*a%MOD;n>>=1;}return res;}
ll qpow(ll a,ll n,ll p){a%=p;ll res =1LL;while(n){if(n&1)res=res*a%p;a=a*a%p;n>>=1;}return res;}
ll npow(ll a,ll n){/* */ll res =1LL;while(n){if(n&1)res=res*a;a=a*a;n>>=1;if(res<0||a<0)return0;}return res;}
ll inv(ll a){/* */returnqpow(a,MOD-2);}
ll inv(ll a,ll p){returnqpow(a,p-2,p);}intmain(){int T;cin >> T;while(T--){
ll s,n,k;
cin >> s >> n >> k;if(s == k)puts("YES");elseif(s < k)puts("NO");else{if(s >= n / k *(k +1)+(n - n / k))puts("NO");elseputs("YES");}}return0;}
【解题报告】CF#747 Div2 | A - FA. Consecutive Sum Riddle *800题意思路代码B. Special Numbers *1100题意思路代码C. Make Them Equal *1200题意思路代码D. The Number of Imposters *1700题意思路代码E1. Rubik's Cube Coloring (easy version) *1300题意思路代码E2. Rubik's Cube Coloring (hard version) *230