给定一个大小为
n
×
n
n\times n
n×n 的网格,每个格子要么为空,要么为
X
X
X,要么为
O
O
O 规定,出现赢局就是行 / 列上有同时有三个相同的
O
O
O 或者
X
X
X
一次操作,你可以翻转一个
X
X
X 变成
O
O
O 或者翻转一个
O
O
O 变成
X
X
X 假设棋盘上有
k
k
k 个棋子,请在最多
⌊
k
3
⌋
\lfloor \frac{k}{3}\rfloor
⌊3k⌋ 步内让棋局没有赢局。
1
≤
n
≤
300
1\le n\le 300
1≤n≤300
你需要输出最后的没有赢局的局面。
思路
感觉如果用各种奇妙的贪心和特判的话,这题会变得特别不好做。 我们先考虑一下,如果一个局面全是
X
X
X 的话,怎么处理?
可以依稀感觉到,对于
a
x
,
y
a_{x,y}
ax,y 的棋子,我们按
(
x
+
y
)
%
3
(x+y)\%3
(x+y)%3 作为三个同余类
S
0
,
S
1
,
S
2
S_0,S_1,S_2
S0,S1,S2去处理。 如果我们定
S
0
S_0
S0 必须为
X
X
X,这样就可以保证不会有
O
O
O 的赢局 如果我们定
S
0
S_0
S0 必须为
O
O
O,这样就可以保证不会有
X
X
X 的赢局 我们不希望有
O
O
O 与
X
X
X 的赢局,我们可以让
S
0
,
S
1
,
S
2
S_0,S_1,S_2
S0,S1,S2 中的两项取出来,满足上述俩要求即可。
接下来是操作上限的证明 容易得到:
S
0
(
X
)
+
S
1
(
X
)
+
S
2
(
X
)
+
S
0
(
O
)
+
S
1
(
O
)
+
S
2
(
O
)
=
k
S_0(X)+S_1(X)+S_2(X)+S_0(O)+S_1(O)+S_2(O)=k
S0(X)+S1(X)+S2(X)+S0(O)+S1(O)+S2(O)=k 所以必定存在一对
S
t
(
X
)
,
S
t
+
1
(
O
)
S_t(X),S_{t+1}(O)
St(X),St+1(O),满足
S
t
(
X
)
+
S
t
+
1
(
O
)
≤
⌊
k
3
⌋
S_t(X)+S_{t+1}(O)\le \lfloor \frac{k}{3} \rfloor
St(X)+St+1(O)≤⌊3k⌋ 当然也存在
S
t
(
O
)
,
S
t
+
1
(
X
)
S_t(O),S_{t+1}(X)
St(O),St+1(X) 也是满足的。
代码
时间复杂度:
O
(
n
2
)
O(n^2)
O(n2)
#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...);}#definelllonglongconstint MAX =3e2+50;char aa[MAX][MAX];intmain(){int T;scanf("%d",&T);while(T--){int n;scanf("%d",&n);int k =0;for(int i =1;i <= n;++i)scanf("%s",aa[i]+1);for(int i =1;i <= n;++i)for(int j =1;j <= n;++j)if(aa[i][j]!='.')k++;for(int t =0;t <3;++t){int cnt =0;for(int i =1;i <= n;++i)for(int j =1;j <= n;++j){if((i+j)%3== t && aa[i][j]=='X')cnt++;if((i+j+1)%3== t && aa[i][j]=='O')cnt++;}if(cnt <= k /3){for(int i =1;i <= n;++i){for(int j =1;j <= n;++j){if((i+j)%3== t && aa[i][j]=='X')aa[i][j]='O';if((i+j+1)%3== t && aa[i][j]=='O')aa[i][j]='X';printf("%c",aa[i][j]);}puts("");}break;}}}return0;}
C:Sonya and Problem Wihtout a Legend | CF713C
题意(在原题上增强)
给定一个长度为
n
n
n 的序列
a
n
a_n
an 每一次操作,可以让一个位置的一个元素值
+
1
+1
+1 或者
−
1
-1
−1 现在问你,让这个序列变为严格单调递增序列的最少操作次数
1
≤
n
≤
1
0
5
1\le n\le 10^5
1≤n≤105
∣
a
i
∣
≤
1
0
9
|a_i|\le 10^9
∣ai∣≤109
这个题目一个是改为单调不递减,一个是改为严格单调递增,但其实是等价的。 假设原数列元素有
a
<
b
<
c
a<b<c
a<b<c 我们令
a
a
≤
b
b
≤
c
c
aa\le bb\le cc
aa≤bb≤cc 其实就是相当于
a
a
<
b
b
−
1
<
c
c
−
2
aa<bb-1<cc-2
aa<bb−1<cc−2 也相当于
a
a
−
1
<
b
b
−
2
<
c
c
−
3
aa-1<bb-2<cc-3
aa−1<bb−2<cc−3 所以,我们原序列中的元素
a
i
a_i
ai 更新为
a
i
=
a
i
−
i
a_i=a_i-i
ai=ai−i,那么严格单调递增问题就可以转化为单调不递减序列问题。 注意到,我们问题之和
a
i
a_i
ai 与
a
j
a_j
aj 的差值有关,而与
a
i
a_i
ai 的具体数值是无关的,因此可以转化。
有一个比较简单的例子。假设
n
=
2
n=2
n=2,有数字
a
,
b
a,b
a,b,其中
a
>
b
a>b
a>b 这个时候,答案一定是
b
−
a
b-a
b−a,方案也很简单,就是
c
∈
[
a
,
b
]
c\in[a,b]
c∈[a,b],然后让
a
,
b
a,b
a,b 都变成
c
c
c 即可。 注意到,如果数列长度比较长,为了让答案不劣,我们令
c
=
a
c=a
c=a 明显是更优的。
假设现在我们处理到
i
i
i 的答案了,其中
a
i
−
1
a_{i-1}
ai−1 我们修改值变为了
a
i
−
1
′
a_{i-1}^\prime
ai−1′ 如果
a
i
≥
a
i
−
1
′
a_i\ge a_{i-1}^\prime
ai≥ai−1′,显然我们不需要修改。 否则,我们需要多操作
a
i
−
1
′
−
a
i
a_{i-1}^\prime-a_i
ai−1′−ai 次操作。
∗
\color{red}{*}
∗ 在形式上,我们可以令
a
i
−
1
′
=
a
i
a_{i-1}^\prime=a_{i}
ai−1′=ai,就像上面的让答案更优。但是可能会使得
a
i
−
1
′
<
a
i
−
2
′
a_{i-1}^\prime<a_{i-2}^\prime
ai−1′<ai−2′,但这并不妨碍我们,因为若我们令
a
i
′
=
a
i
−
1
′
a_i^\prime=a_{i-1}^\prime
ai′=ai−1′,也是多操作了这些步骤,且保证一定是合法的。若
a
i
−
1
′
<
a
i
−
2
′
a_{i-1}^\prime<a_{i-2}^\prime
ai−1′<ai−2′ 成立了,我们变 假装 调整这个序列,通过如下的手段:
4
≤
n
≤
1
0
18
4\le n\le 10^{18}
4≤n≤1018
1
≤
f
1
,
f
2
,
f
3
≤
1
0
9
1\le f_1,f_2,f_3\le 10^9
1≤f1,f2,f3≤109
思路
之前看有人牛客群里问了
f
x
=
f
x
−
1
f
x
−
2
f_x=f_{x-1}f_{x-2}
fx=fx−1fx−2 的问题咋做,随机就拉到了这题… 一个很标准的矩阵快速幂的题目,会写的应该都会,稍微变变即可。
第一步,我们记录每个数字
f
x
=
f
1
a
×
f
2
b
×
f
3
c
×
o
t
h
e
r
s
f_x=f_1^{a}\times f_2^b\times f_3^c\times others
fx=f1a×f2b×f3c×others,算出次数
a
,
b
,
c
a,b,c
a,b,c 容易想到,对于乘积来说,次方是相加的。我们容易写出转移:
(
1
1
1
1
0
0
0
1
0
)
(
f
n
(
a
)
f
n
(
b
)
f
n
(
c
)
f
n
−
1
(
a
)
f
n
−
1
(
b
)
f
n
−
1
(
c
)
f
n
−
2
(
a
)
f
n
−
2
(
b
)
f
n
−
2
(
c
)
)
=
(
f
n
+
1
(
a
)
f
n
+
1
(
b
)
f
n
+
1
(
c
)
f
n
(
a
)
f
n
(
b
)
f
n
(
c
)
f
n
−
1
(
a
)
f
n
−
1
(
b
)
f
n
−
1
(
c
)
)
\begin{pmatrix} 1&1&1\\ 1&0&0\\ 0&1&0\\ \end{pmatrix} \begin{pmatrix} f_n(a)&f_n(b)&f_n(c)\\ f_{n-1}(a)&f_{n-1}(b)&f_{n-1}(c)\\ f_{n-2}(a)&f_{n-2}(b)&f_{n-2}(c)\\ \end{pmatrix} = \begin{pmatrix} f_{n+1}(a)&f_{n+1}(b)&f_{n+1}(c)\\ f_n(a)&f_n(b)&f_n(c)\\ f_{n-1}(a)&f_{n-1}(b)&f_{n-1}(c)\\ \end{pmatrix}
⎝⎛110101100⎠⎞⎝⎛fn(a)fn−1(a)fn−2(a)fn(b)fn−1(b)fn−2(b)fn(c)fn−1(c)fn−2(c)⎠⎞=⎝⎛fn+1(a)fn(a)fn−1(a)fn+1(b)fn(b)fn−1(b)fn+1(c)fn(c)fn−1(c)⎠⎞ 所以可以得出:
(
1
1
1
1
0
0
0
1
0
)
n
−
3
(
0
0
1
0
1
0
1
0
0
)
=
(
f
n
(
a
)
f
n
(
b
)
f
n
(
c
)
f
n
−
1
(
a
)
f
n
−
1
(
b
)
f
n
−
1
(
c
)
f
n
−
2
(
a
)
f
n
−
2
(
b
)
f
n
−
2
(
c
)
)
\begin{pmatrix} 1&1&1\\ 1&0&0\\ 0&1&0\\ \end{pmatrix}^{n-3} \begin{pmatrix} 0&0&1\\ 0&1&0\\ 1&0&0\\ \end{pmatrix} = \begin{pmatrix} f_n(a)&f_n(b)&f_n(c)\\ f_{n-1}(a)&f_{n-1}(b)&f_{n-1}(c)\\ f_{n-2}(a)&f_{n-2}(b)&f_{n-2}(c)\\ \end{pmatrix}
⎝⎛110101100⎠⎞n−3⎝⎛001010100⎠⎞=⎝⎛fn(a)fn−1(a)fn−2(a)fn(b)fn−1(b)fn−2(b)fn(c)fn−1(c)fn−2(c)⎠⎞
第二步,算出那个
f
x
=
c
d
×
o
t
h
e
r
s
f_x=c^d\times others
fx=cd×others 底数为
c
c
c 的指数是多少,相同的道理,写出转移矩阵
(
1
1
1
1
1
−
2
1
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
1
1
0
0
0
0
0
1
)
×
(
c
i
c
i
−
1
c
i
−
2
2
i
2
)
=
(
c
i
+
1
c
i
c
i
−
1
2
(
i
+
1
)
2
)
\begin{pmatrix} 1&1&1&1&1&-2\\ 1&0&0&0&0&0\\ 0&1&0&0&0&0\\ 0&0&0&0&1&1\\ 0&0&0&0&0&1\\ \end{pmatrix} \times \begin{pmatrix} c_i\\ c_{i-1}\\ c_{i-2}\\ 2i\\ 2 \end{pmatrix} = \begin{pmatrix} c_{i+1}\\ c_{i}\\ c_{i-1}\\ 2(i+1)\\ 2 \end{pmatrix}
⎝⎜⎜⎜⎜⎛1100010100100001000010010−20011⎠⎟⎟⎟⎟⎞×⎝⎜⎜⎜⎜⎛cici−1ci−22i2⎠⎟⎟⎟⎟⎞=⎝⎜⎜⎜⎜⎛ci+1cici−12(i+1)2⎠⎟⎟⎟⎟⎞ 所以我们有:
(
1
1
1
1
1
−
2
1
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
1
1
0
0
0
0
0
1
)
n
−
4
×
(
14
6
2
12
2
)
=
(
c
n
+
2
c
n
+
1
c
n
2
(
n
+
2
)
2
)
\begin{pmatrix} 1&1&1&1&1&-2\\ 1&0&0&0&0&0\\ 0&1&0&0&0&0\\ 0&0&0&0&1&1\\ 0&0&0&0&0&1\\ \end{pmatrix}^{n-4} \times \begin{pmatrix} 14\\ 6\\ 2\\ 12\\ 2 \end{pmatrix} = \begin{pmatrix} c_{n+2}\\ c_{n+1}\\ c_{n}\\ 2(n+2)\\ 2 \end{pmatrix}
⎝⎜⎜⎜⎜⎛1100010100100001000010010−20011⎠⎟⎟⎟⎟⎞n−4×⎝⎜⎜⎜⎜⎛1462122⎠⎟⎟⎟⎟⎞=⎝⎜⎜⎜⎜⎛cn+2cn+1cn2(n+2)2⎠⎟⎟⎟⎟⎞
还有一点注意的,由于这里的数字都是指数,根据欧拉降幂,需要取模
φ
(
P
)
=
P
−
1
\varphi(P)=P-1
φ(P)=P−1
代码
时间复杂度:
O
(
s
z
3
×
log
n
)
O(sz^3\times \log n)
O(sz3×logn)
#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...);}#definelllonglongconstint MAX =3e2+50;constint MOD =1e9+6;constint MOD2 =1e9+7;typedeflonglong Elemtype;constint SZ =5;structMatrix{
Elemtype mat[SZ][SZ];}M1,M2,M3,M0;
Matrix mul(Matrix x,Matrix y,ll sz){
Matrix ans;for(int i=0;i<sz;++i){for(int j=0;j<sz;++j){
ans.mat[i][j]=0;for(int k=0;k<sz;++k){
ans.mat[i][j]+=(x.mat[i][k]*y.mat[k][j])%MOD;}
ans.mat[i][j]%=MOD;}}return ans;}
ll qpow(ll a, ll n,ll pmod){
ll ans =1;while(n){if(n&1){
ans=ans*a%pmod;}
n>>=1;
a=a*a%pmod;}return ans;}
Matrix Create_Matrix(ll sz){
Matrix ans;for(ll i=0;i<sz;++i)for(ll j=0;j<sz;++j)if(i==j)ans.mat[i][j]=1;else ans.mat[i][j]=0;return ans;}
Matrix M_qpow(Matrix x,ll n,ll sz){
Matrix ans =Create_Matrix(sz);while(n){if(n&1){
ans =mul(ans,x,sz);}
n>>=1;
x =mul(x,x,sz);}return ans;}voidshow_M(Matrix x,int sz){puts("---");for(int i =0;i < sz;++i){for(int j =0;j < sz;++j){
cout << x.mat[i][j]<<" ";}puts("");}puts("---");}intmain(){
ll n,a,b,c,d;
ll ans =0;
cin >> n >> a >> b >> c >> d;
M1.mat[0][0]= M1.mat[0][1]= M1.mat[0][2]=1;
M1.mat[1][0]= M1.mat[2][1]=1;
M1 =M_qpow(M1,n-3,3);
M0.mat[0][2]= M0.mat[1][1]= M0.mat[2][0]=1;
M1 =mul(M1,M0,3);
ans =qpow(a,M1.mat[0][0],MOD2)*qpow(b,M1.mat[0][1],MOD2)% MOD2 *qpow(c,M1.mat[0][2],MOD2)% MOD2;
M2.mat[0][0]= M2.mat[0][1]= M2.mat[0][2]= M2.mat[0][3]=1;
M2.mat[0][4]=(-2+ MOD);
M2.mat[1][0]= M2.mat[2][1]= M2.mat[3][3]= M2.mat[3][4]= M2.mat[4][4]=1;
M2 =M_qpow(M2,n-4,5);
M3.mat[0][0]=14;
M3.mat[1][0]=6;
M3.mat[2][0]=2;
M3.mat[3][0]=12;
M3.mat[4][0]=2;
M3 =mul(M2,M3,5);
ans = ans *qpow(d,M3.mat[2][0],MOD2)% MOD2;printf("%lld",ans);return0;}
前置:
∗
\color{red}{*}
∗
x
n
−
1
=
(
x
−
1
)
(
x
n
−
1
+
x
n
−
2
+
⋯
+
1
)
x^n-1=(x-1)(x^{n-1}+x^{n-2}+\cdots+1)
xn−1=(x−1)(xn−1+xn−2+⋯+1)
∗
\color{red}{*}
∗
x
n
+
1
=
(
x
+
1
)
(
x
n
−
1
−
x
n
−
2
+
⋯
+
1
)
x^n+1=(x+1)(x^{n-1}-x^{n-2}+\cdots+1)
xn+1=(x+1)(xn−1−xn−2+⋯+1) 其中
n
n
n 是奇数
首先是最简单的
2
−
t
y
p
e
2-type
2−type 注意到,也就是我们希望满足
d
×
k
=
b
x
d\times k=b^x
d×k=bx 对于最小的正整数
x
x
x 和一个正整数
k
k
k 成立。 注意到,此时
d
d
d 的所有质因子都必须包含于
b
b
b 的所有质因子。 代码实现上,若
gcd
(
d
,
b
)
≠
1
\gcd(d,b)\ne 1
gcd(d,b)=1,则我们每次让
d
=
d
/
gcd
(
d
,
b
)
d=d/\gcd(d,b)
d=d/gcd(d,b),没除一次,则
x
=
x
+
1
x=x+1
x=x+1 此时若
d
=
1
d=1
d=1,则就是
2
−
t
y
p
e
2-type
2−type,此时的
x
x
x 就是最小的
x
x
x
然后就是
3
,
11
,
6
−
t
y
p
e
3,11,6-type
3,11,6−type 看
3
−
t
y
p
e
3-type
3−type,我们需要把
b
b
b 进制下的
d
d
d 写出来。
d
=
∑
i
=
0
∞
a
i
b
i
d=\sum_{i=0}^\infin a_ib^i
d=i=0∑∞aibi 注意到此时我们当然有
∑
i
=
0
∞
a
i
b
i
≡
0
(
m
o
d
d
)
\sum_{i=0}^\infin a_ib^i \equiv 0\pmod d
i=0∑∞aibi≡0(modd) 对于
3
−
t
y
p
e
3-type
3−type,我们有
∑
i
=
0
∞
a
i
≡
0
(
m
o
d
d
)
\sum_{i=0}^\infin a_i \equiv 0\pmod d
i=0∑∞ai≡0(modd) 两式子合并,得到:
∑
i
=
0
∞
a
i
(
b
i
−
1
)
≡
0
(
m
o
d
d
)
∑
i
=
0
∞
a
i
(
b
−
1
)
(
o
t
h
e
r
s
)
≡
0
(
m
o
d
d
)
\sum_{i=0}^\infin a_i(b^i-1) \equiv 0\pmod d\\ \sum_{i=0}^\infin a_i(b-1)(others) \equiv 0\pmod d\\
i=0∑∞ai(bi−1)≡0(modd)i=0∑∞ai(b−1)(others)≡0(modd) 也就是说
b
−
1
b-1
b−1 是
d
d
d 的倍数
然后是
11
−
t
y
p
e
11-type
11−type,同理
∑
i
=
0
∞
a
i
b
i
≡
0
(
m
o
d
d
)
∑
i
=
0
∞
(
−
1
)
i
+
1
a
i
≡
0
(
m
o
d
d
)
\sum_{i=0}^\infin a_ib^i \equiv 0\pmod d\\ \sum_{i=0}^\infin (-1)^{i+1}a_i\equiv 0\pmod d
i=0∑∞aibi≡0(modd)i=0∑∞(−1)i+1ai≡0(modd) 得到以下式子:
∑
i
=
0
∞
a
i
(
b
i
+
(
−
1
)
i
+
1
)
≡
0
(
m
o
d
d
)
\sum_{i=0}^\infin a_i(b^i+(-1)^{i+1}) \equiv 0\pmod d\\
i=0∑∞ai(bi+(−1)i+1)≡0(modd) 若
i
i
i 是奇数,则会变成
b
J
+
1
=
(
b
+
1
)
(
O
t
h
e
r
s
)
b^J+1=(b+1)(Others)
bJ+1=(b+1)(Others) 的形式 若
i
i
i 是偶数,则会变成
b
2
x
−
1
=
(
b
x
+
1
)
(
b
x
−
1
)
b^{2x}-1=(b^x+1)(b^x-1)
b2x−1=(bx+1)(bx−1) 若
x
x
x 是奇数,那么左边这一项可以分出来一个
(
b
+
1
)
(
O
t
h
e
r
s
)
(b+1)(Others)
(b+1)(Others);若
x
x
x 是偶数,那么继续拆
b
x
−
1
b^x-1
bx−1,就是一个递归问题了。
所以此时一定有
1
+
b
1+b
1+b 是
d
d
d 的倍数 注意,以上两种都要求
x
=
0
x=0
x=0,也就是
gcd
(
b
,
d
)
=
1
\gcd(b,d)=1
gcd(b,d)=1
6
−
t
y
p
e
6-type
6−type,也就是上述有两种同时满足,就是
b
+
1
和
b
−
1
b+1和 b-1
b+1和b−1 同时是
d
d
d 的倍数即可。
∗
\color{red}{*}
∗ 如果符合
3
−
t
y
p
e
3-type
3−type 或者
11
−
t
y
p
e
11-type
11−type,那么一定符合
2
−
t
y
p
e
2-type
2−type 否则就是
7
−
t
y
p
e
7-type
7−type
代码
时间复杂度:
O
(
log
R
)
O(\log R)
O(logR)
#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...);}#definelllonglongconstint MAX =3e2+50;constint MOD =1e9+6;intlcm(int x,int y){return x * y /__gcd(x,y);}intmain(){int b,d,dd,cnt =0;
cin >> b >> d;
dd = d;while(__gcd(dd,b)>1){
dd /=__gcd(dd,b);
cnt++;}if(dd ==1){puts("2-type");printf("%d",cnt);}elseif(!(lcm(b-1,b+1)% dd)){if(!cnt &&!((b-1)% dd))puts("3-type");elseif(!cnt &&!((b+1)% dd))puts("11-type");elseputs("6-type");}else{puts("7-type");}return0;}