QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#482333 | #4222. 题 | Fffoooo | 100 ✓ | 805ms | 503936kb | C++14 | 4.4kb | 2024-07-17 18:57:36 | 2024-07-17 18:57:36 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
int mian(); int main() { return mian(); }
/*
给定常为 $3n$,值域为 $[0,3]$ 的序列 $S$,可以将其中的 $0$ 更改为 $[1,3]$ 得到 $T$
求出对所有 $T$,合法的 $a$ 的数量的和
合法的 $a$ 表示为长为 $n$ 的三元序列 ${a_{i,1},a_{i,2},a_{i,3}}$ ,满足
$(T_{a_{i,1}},T_{a_{i,2}},T_{a_{i,3}})=(1,3,2)\space or\space (2,1,3)\space or\space (3,2,1)$
且 $a_{i,1}<a_{i,2}<a_{i,3}$ ,每个 $a$ 互不相同
$n\le 19, mod = 10^9+7$
$1s,1G$
因为只有三种形态,那么每一次新加入的一个字符,就是要让这个字符与之前的某个未完成的前缀 $a$ 进行匹配,或者继续成为一个未完成的前缀
因为空间很大,直接设计 `f[i][j][k][o][p][q]`,表示到当前位置(状态中省略,滚动),已经有 $(i,j,k,o,p,q)$ 个未完成匹配的前缀是 $(1, 2, 3, 13, 21, 32)$
每一次直接根据这一位是什么转移即可,时间复杂度 $O(3*n^7)$,因为还要枚举当前位置,但是因为状态和只有 $n$,因此存在巨大的常数
答案即为没有任何前缀没有匹配,即全为 $0$
注意题目中的 $a$ 之间是互相没有限制,即每一个匹配完成的 $a$ 可以在任何顺序,因此要加上一个阶乘
同理,转移过程中的每一步都要在所有的方案中选择一个数字转移,因此每一步都要乘上选走的东西的方案数(就是与这个数拼接的所有前缀都可以选且是不同的,因此每种方案都要计算)
注意只需要乘上选择某一个数的方案而不需要乘上放入的方案,因为放入时是无序的,所以取出时才需要选择
*/
#define ll long long
const int N = 20;
const int mod = 1e9 + 7;
int n, S;
int f[2][N][N][N][N][N][N];
#define FOR \
for(int i = 0; i <= n; ++i) \
for(int j = 0; j + i <= n; ++j) \
for(int k = 0; i + j + k <= n; ++k) \
for(int o = 0; i + j + k + o <= n; ++o) \
for(int p = 0; i + j + k + o + p <= n; ++p) \
for(int q = 0; i + j + k + o + p + q <= n; ++q)
//多一个1,多一个21,多一个完成匹配
void doo1(const int now) {
FOR f[now][i][j][k][o][p][q] = ( ( i ? (ll)f[now ^ 1][i - 1][j][k][o][p][q] : 0 ) + ( p and j < n ? (ll)f[now ^ 1][i][j + 1][k][o][p - 1][q] * (j + 1) % mod : 0 ) + ( q < n ? (ll)f[now ^ 1][i][j][k][o][p][q + 1] * (q + 1) % mod : 0 ) ) % mod;
}
void doo2(const int now) {
FOR f[now][i][j][k][o][p][q] = ( ( j ? (ll)f[now ^ 1][i][j - 1][k][o][p][q] : 0 ) + ( q and k < n ? (ll)f[now ^ 1][i][j][k + 1][o][p][q - 1] * (k + 1) % mod : 0 ) + ( o < n ? (ll)f[now ^ 1][i][j][k][o + 1][p][q] * (o + 1) % mod : 0 ) ) % mod;
}
void doo3(const int now) {
FOR f[now][i][j][k][o][p][q] = ( ( k ? (ll)f[now ^ 1][i][j][k - 1][o][p][q] : 0 ) + ( o and i < n ? (ll)f[now ^ 1][i + 1][j][k][o - 1][p][q] * (i + 1) % mod : 0 ) + ( p < n ? (ll)f[now ^ 1][i][j][k][o][p + 1][q] * (p + 1) % mod : 0 ) ) % mod;
}
void doo0(const int now) {
FOR f[now][i][j][k][o][p][q] = ( ( i ? (ll)f[now ^ 1][i - 1][j][k][o][p][q] : 0 ) + ( p and j < n ? (ll)f[now ^ 1][i][j + 1][k][o][p - 1][q] * (j + 1) % mod : 0 ) + ( q < n ? (ll)f[now ^ 1][i][j][k][o][p][q + 1] * (q + 1) % mod : 0 ) +
( j ? (ll)f[now ^ 1][i][j - 1][k][o][p][q] : 0 ) + ( q and k < n ? (ll)f[now ^ 1][i][j][k + 1][o][p][q - 1] * (k + 1) % mod : 0 ) + ( o < n ? (ll)f[now ^ 1][i][j][k][o + 1][p][q] * (o + 1) % mod : 0 ) +
( k ? (ll)f[now ^ 1][i][j][k - 1][o][p][q] : 0 ) + ( o and i < n ? (ll)f[now ^ 1][i + 1][j][k][o - 1][p][q] * (i + 1) % mod : 0 ) + ( p < n ? (ll)f[now ^ 1][i][j][k][o][p + 1][q] * (p + 1) % mod : 0 ) ) % mod;
}
void out(const int now, const int it) {
FOR if(f[now][i][j][k][o][p][q]) printf("%d f[%d][%d][%d][%d][%d][%d]=%d\n", it, i, j, k, o, p, q, f[now][i][j][k][o][p][q]);
}
void solve() {
scanf("%d", &n);
memset(f, 0, sizeof f);
f[1][0][0][0][0][0][0] = 1;
int now = 0;
int fac = 1;
for(int i = 1; i <= 3 * n; ++i) {
scanf("%1d", &S);
if( i <= n ) fac = (ll)fac * i % mod;
switch(S) {
case 1 : { doo1(now); break; }
case 2 : { doo2(now); break; }
case 3 : { doo3(now); break; }
default: { doo0(now); }
}
now ^= 1;
}
printf("%lld\n", (ll)fac * f[now ^ 1][0][0][0][0][0][0] % mod);
}
int mian() {
int T; scanf("%d", &T);
while(T--) solve();
return 0;
} /*
1
19
202000300003001300011000011021320001000300320020302022103
*/
详细
Test #1:
score: 10
Accepted
time: 181ms
memory: 503740kb
input:
5 1 123 1 100 1 000 1 300 1 010
output:
0 1 3 1 1
result:
ok 5 lines
Test #2:
score: 10
Accepted
time: 169ms
memory: 503740kb
input:
5 1 303 2 000320 2 002000 2 002020 2 020020
output:
0 36 60 12 12
result:
ok 5 lines
Test #3:
score: 10
Accepted
time: 166ms
memory: 503788kb
input:
5 2 110133 3 200010000 3 002002200 3 300000000 3 000000130
output:
0 5940 540 15120 7560
result:
ok 5 lines
Test #4:
score: 10
Accepted
time: 188ms
memory: 503732kb
input:
5 5 000000000000000 4 000000000000 3 000000000 2 000000 1 000
output:
864823720 29937600 45360 180 3
result:
ok 5 lines
Test #5:
score: 10
Accepted
time: 168ms
memory: 503936kb
input:
5 6 000121310223223210 7 033221120002010100230 7 000003020000010302010 7 000010002020302300100 7 030100002033300000000
output:
26853120 152413083 939384999 4309685 970165754
result:
ok 5 lines
Test #6:
score: 10
Accepted
time: 174ms
memory: 503792kb
input:
5 9 120332011311030220200103301 10 200003200103011232000202201120 10 000000201330030030101000003000 10 020000002032000000200000100002 10 100200322001000000320000002010
output:
963757075 290911546 487693965 730680478 984422198
result:
ok 5 lines
Test #7:
score: 10
Accepted
time: 202ms
memory: 503800kb
input:
5 13 000000000000000000000000000000000000000 12 000000000000000000000000000000000000 11 000000000000000000000000000000000 10 000000000000000000000000000000 9 000000000000000000000000000
output:
856865849 574346463 607449787 883895867 88660419
result:
ok 5 lines
Test #8:
score: 10
Accepted
time: 399ms
memory: 503872kb
input:
5 15 331110203302222220331213331310312220103030021 16 001301022200100032010330002213000300220033210033 16 020002030002000330003200030010000000000100002300 16 320000001003222000003000003000300010323113200020 16 000203000000000000010100000000000000002000210000
output:
70336694 482512438 740138646 212387388 427674884
result:
ok 5 lines
Test #9:
score: 10
Accepted
time: 649ms
memory: 503776kb
input:
5 17 221001103220113003322101120223031133120301212031002 18 201000020000000010323100000333030002012000213100030001 18 013203020100001021200030003102000130000002330303302120 18 010003030200000200100000002000000000000302000203103300 18 000001000132020000200321023010000000000000000132210300
output:
821788453 589132243 303959134 648206569 571580782
result:
ok 5 lines
Test #10:
score: 10
Accepted
time: 805ms
memory: 503792kb
input:
5 18 331110100201233220121012022130200011112133012123201012 19 221011310310012302220013020123002132313030023020101110230 19 202000300003001300011000011021320001000300320020302022103 19 010030200000000000300300310000001302002000010230000330020 19 000000000000031000000000131200020001000020000001020000...
output:
171958822 242716134 229925968 914555153 59496792
result:
ok 5 lines
Extra Test:
score: 0
Extra Test Passed