2021.8.22 校测
期望得分 : \(100 + 60 + 20 = 180\)
实际得分 : \(10 + 60 + 0 = 70\)
【T1 套路 】
我吐了,就差一个地方 ,硬是调一个小时没看出来。
description :
给定一个一张 \(n\) 条边的有向图,现在让你将边重定向,计算其没有环方案数,并对 \(10^9 + 7\) 取模 。
$Notice : $ 每一个点只有 \(1\) 个出度。
Solution :
我们发现在原本的图中,如果有环,那么我们任意调换这个环中的边其实都可以形成正确的方案。
有一个值得注意的地方就是 : 每一个点只有一个出度
那么这句话就代表了,这张图只会是一个个的强连通分量,也就是环。
那么我们任意翻转 : 一个环有 \(n\) 个点,就有 \(n\) 条边,既然有 \(n\) 条边,那么也就对应着 \(2 ^n\) 的可能。直接算就行。
不过值得注意的就是 : 这一个环,有两种情况需要减去:
- 全部都翻转过来 (它还是个环,我就忘记了,导致一直输出 \(21\) , 怎么也调不出来)
- 全部都不翻转(没意义)
Code , 正解不正解已经没有意义了,就差一个地方
//
/*
Author : Zmonarch
Knowledge : Tarjan + 组合数学
*/
#include <bits/stdc++.h>
#define qwq register
#define qaq inline
#define int long long
#define inf 2147483647
using namespace std ;
const int kmaxn = 1e6 + 10 ;
const int mod = 1e9 + 7 ;
qaq int read() {
int x = 0 , f = 1 ; char ch = getchar() ;
while(!isdigit(ch)) {if(ch == '-') f = - 1 ; ch = getchar() ;}
while( isdigit(ch)) {x = x * 10 + ch - '0' ; ch = getchar() ;}
return x * f ;
}
int tot , n , m , cnt , Dfn , top , Ans = 1 ;
struct node {
int nxt , u , v ;
}e[kmaxn << 1] ;
int h[kmaxn] , siz[kmaxn] , in[kmaxn] ;
int low[kmaxn] , dfn[kmaxn] , sta[kmaxn] ;
qaq void add(int u , int v) {
e[++tot].nxt = h[u] ;
e[tot].u = u ; e[tot].v = v ;
h[u] = tot ;
}
qaq void Tarjan(int u) {
dfn[u] = low[u] = ++ Dfn ; sta[++top] = u ;
for(qwq int i = h[u] ; i ; i = e[i].nxt)
{
int v = e[i].v ;
if(!dfn[v]) Tarjan(v) , low[u] = min(low[u] , low[v]) ;
else if(!in[v]) low[u] = min(low[u] , dfn[v]) ;
}
if(low[u] == dfn[u])
{
in[u] = ++ cnt ; siz[cnt]++ ;
while(sta[top] != u)
{
in[sta[top--]] = cnt ;
siz[cnt]++ ;
}
}
}
qaq int Qpow(int a , int b) {
int ret = 1;
while(b)
{
if(b & 1) ret = ret * a % mod ;
a = a * a % mod ; b >>= 1 ;
}
return ret ;
}
signed main() {
//freopen("road.in" , "r" , stdin) ;
//freopen("road.out" , "w" , stdout) ;
n = read() ;
for(qwq int i = 1 ; i <= n ; i++)
{
int x = read() ;
add(i , x) ;
}
for(qwq int i = 1 ; i <= n ; i++)
if(!dfn[i]) Tarjan(i) ;
for(qwq int i = 1 ; i <= cnt ; i++)
{
if(siz[i] == 1) Ans = Ans * 2 % mod ; // 这里需要特判一下。
else Ans = Ans * (Qpow(2 , siz[i]) - 2) % mod ;
}
printf("%lld\n" , Ans) ;
return 0 ;
}
【T2exLCS】
这题数据是真的水。
我考场看错题目,写的一个匹配前缀和我写的朴素暴力一个分数。都是 \(60\) , 我吐了。
Description :
求解两个串 \(s_1 , s_2\) 的最长公共子序列,子序列可不连续 。
\(l_{s_1} \leq 10^3 , l_{s_2} \leq 10^6\)
Solution :
模板题,但是我只想着 \(n^2\) 。
Code :
//
/*
Author : Zmonarch
Knowledge :
*/
#include <bits/stdc++.h>
#define qwq register
#define qaq inline
#define int long long
#define inf 2147483647
using namespace std ;
const int kmaxn = 1e6 + 10 ;
const int N = 1e3 + 10 ;
qaq int read() {
int x = 0 , f = 1 ; char ch = getchar() ;
while(!isdigit(ch)) {if(ch == '-') f = - 1 ; ch = getchar() ;}
while( isdigit(ch)) {x = x * 10 + ch - '0' ; ch = getchar() ;}
return x * f ;
}
int len1 , len2;
char s1[kmaxn] , s2[kmaxn] ;
int f[N][N] , nxt[kmaxn][26] ;
signed main(){
cin >> s1 >> s2 ; len1 = strlen(s1) , len2 = strlen(s2) ;
for(qwq int i = 0 ; i <= len1 ; i++)
for(qwq int j = 0 ; j <= len1 ; j++)
f[i][j] = inf ;
for(qwq int i = 0 ; i <= 25; i++)
nxt[len2][i] = inf ;
for(qwq int i = len2 - 1; i >= 0; i--)
{
memcpy(nxt[i] , nxt[i + 1] , sizeof(nxt[i])) ;
nxt[i][s2[i] - 'a'] = i ;
}
f[0][1] = nxt[0][s1[0] - 'a'] ;
for(qwq int i = 0 ; i <= len1 ; i++) f[i][0] = - 1;
for(qwq int i = 0 ; i < len1 - 1 ; i++)
for(qwq int j = 0 ; j <= len1 && f[i][j] < inf ; j++)
{
f[i + 1][j] = min(f[i + 1][j] , f[i][j]) ;
if(j < len1) f[i + 1][j + 1] = min(f[i + 1][j + 1] , nxt[f[i][j] + 1][s1[i + 1] - 'a']) ;
}
for(qwq int i = len1 ; i ; i--)
if(f[len1 - 1][i] < inf) return printf("%lld\n" , i) , 0 ;
return 0 ;
}
【T3 魔方】
我竟然顺时针逆时针都没分清楚 ,写的 \(20\) 分暴力,每一个面的三种情况调换一下就有 \(20\) 了, 我吐了。
Description : 见题面
Subtask 1 : n = 1
直接模拟即可。我有点无语 。
因为有两面是相对的,所以我们只要模拟 \(3\) 个面就好了。
if(n == 1)
{
if((c[1] == c[2] && c[2] == c[3] && c[3] == c[4])) // 顶
{
if(c[5] == c[15] && c[6] == c[16]) printf("3\n") ;
else if(c[9] == c[15] && c[10] == c[16]) printf("2\n") ;
else printf("1\n") ;
}
else if((c[9] == c[10] && c[10] == c[11] && c[11] == c[12])) // 左
{
if(c[1] == c[6] && c[3] == c[7]) printf("6\n") ;
else if(c[1] == c[20] && c[2] == c[18]) printf("5\n") ;
else printf("4\n") ;
}
else if(c[5] == c[6] && c[6] == c[7] && c[7] == c[8]) // 前
{
if(c[3] == c[14] && c[4] == c[16]) printf("9\n") ;
else if(c[3] == c[18] && c[4] == c[20]) printf("8\n") ;
else printf("7\n") ;
}
}
Subtask 2 : 100 opts
暴力模拟, \(dfs\) 搜索方案 。
//
/*
Author : Zmonarch
Knowledge :
*/
#include <bits/stdc++.h>
#define qwq register
#define qaq inline
#define int long long
#define inf 2147483647
using namespace std ;
const int kmaxn = 1e6 + 10 ;
qaq int read() {
int x = 0 , f = 1 ; char ch = getchar() ;
while(!isdigit(ch)) {if(ch == '-') f = - 1 ; ch = getchar() ;}
while( isdigit(ch)) {x = x * 10 + ch - '0' ; ch = getchar() ;}
return x * f ;
}
bool flag ;
int n ;
int work[25] , opt[kmaxn] ;
qaq void Solve() {
if((work[1] == work[2] && work[2] == work[3] && work[3] == work[4])) // 顶
{
if(work[5] == work[15] && work[6] == work[16]) printf("3\n") ;
else if(work[9] == work[15] && work[10] == work[16]) printf("2\n") ;
else printf("1\n") ;
}
else if((work[9] == work[10] && work[10] == work[11] && work[11] == work[12])) // 左
{
if(work[1] == work[6] && work[3] == work[7]) printf("6\n") ;
else if(work[1] == work[20] && work[2] == work[18]) printf("5\n") ;
else printf("4\n") ;
}
else if(work[5] == work[6] && work[6] == work[7] && work[7] == work[8]) // 前
{
if(work[3] == work[14] && work[4] == work[16]) printf("9\n") ;
else if(work[3] == work[18] && work[4] == work[20]) printf("8\n") ;
else printf("7\n") ;
}
}
qaq void Modify(int id) {
if(id == 1)
{
int a = work[5] , b = work[6] , c = work[1] ;
work[5] = work[13] ; work[6] = work[14] ;
work[13] = work[24] ; work[14] = work[23] ;
work[23] = work[10] ; work[24] = work[9] ;
work[9] = a ; work[10] = b ; work[1] = work[3] ;
work[3] = work[4] ; work[4] = work[2] ; work[2] = c ;
}
else if(id == 2)
{
swap(work[5] , work[24]) ; swap(work[6] , work[23]) ;
swap(work[13] , work[9]) ; swap(work[14] , work[10]) ;
swap(work[1] , work[4]) ; swap(work[2] , work[3]) ;
}
else if(id == 3)
{
int a = work[5] , b = work[6] , c = work[1] ;
work[5] = work[9] ; work[6] = work[10] ;
work[9] = work[24] ; work[10] = work[23] ;
work[23] = work[14] ; work[24] = work[13] ;
work[13] = a ; work[14] = b ; work[1] = work[2] ;
work[2] = work[4] ; work[4] = work[3] ; work[3] = c ;
}
else if(id == 4)
{
int a = work[1] , b = work[3] , c = work[9] ;
work[1] = work[21] ; work[3] = work[23] ;
work[21] = work[17] ; work[23] = work[19] ;
work[17] = work[5] ; work[19] = work[7] ;
work[5] = a ; work[7] = b ; work[9] = work[11] ;
work[11] = work[12] ; work[12] = work[10] ; work[10] = c ;
}
else if(id == 5)
{
swap(work[1] , work[17]) ; swap(work[3] , work[19]) ;
swap(work[5] , work[21]) ; swap(work[7] , work[23]) ;
swap(work[9] , work[12]) ; swap(work[10] , work[11]) ;
}
else if(id == 6)
{
int a = work[1] , b = work[3] , c = work[9] ;
work[1] = work[5] ; work[3] = work[7] ;
work[5] = work[17] ; work[7] = work[19] ;
work[17] = work[21] ; work[19] = work[23];
work[21] = a ; work[23] = b ;
work[9] = work[10] ; work[10] = work[12] ; work[12] = work[11] ; work[11] = c ;
}
else if(id == 7)
{
int a = work[3] , b = work[4] , c = work[5] ;
work[3] = work[12] ; work[4] = work[10] ;
work[10] = work[17] ; work[12] = work[18] ;
work[17] = work[15] ; work[18] = work[13] ;
work[13] = a ; work[15] = b ;
work[5] = work[7] ; work[7] = work[8] ; work[8] = work[6] ; work[6] = c ;
}
else if(id == 8)
{
swap(work[3] , work[18]) ; swap(work[4] , work[17]) ;
swap(work[13] , work[12]) ; swap(work[15] , work[10]) ;
swap(work[5] , work[8]) ; swap(work[6] , work[7]) ;
}
else if(id == 9)
{
int a = work[3] , b = work[4] , c = work[5] ;
work[3] = work[13] ; work[4] = work[15] ;
work[13] = work[18] ; work[15] = work[17] ;
work[17] = work[10] ; work[18] = work[12] ;
work[12] = a ; work[10] = b ;
work[5] = work[6] ; work[6] = work[8] ; work[8] = work[7] ; work[7] = c ;
}
}
qaq void Dfs(int x , int lst) {
bool tag = 0 ;
for(qwq int i = 0 ; i < 6 ; i++)
{
int tmp = work[(i * 4) + 1] ;
for(qwq int j = 1 ; j <= 4 ; j++)
if(work[(i * 4) + j] != tmp)
{
tag = 1 ; break;
}
if(tag) break ;
}
if(!tag)
{
flag = 1 ; x-- ;
for(qwq int i = 1 ; i < x ; i++) printf("%lld " , opt[i]) ;
printf("%lld\n" , opt[x]) ;
return ;
}
if(x == n + 1) return ;
int a[25] ;
for(qwq int i = 0 ; i < 6 ; i++)
for(qwq int j = 1 ; j <= 4 ; j++)
a[(i * 4) + j] = work[(i * 4) + j] ;
for(qwq int i = 0 ; i <= 2 ; i++)
{
if(lst == i) continue ;
for(qwq int j = (i * 3 + 1) ; j <= (i * 3 + 3) ; j++)
{
if(flag) return ;
Modify(j) ; opt[x] = j ;
Dfs(x + 1 , i) ;
if(flag) return ;
for(qwq int k = 0 ; k < 6 ; k++)
for(qwq int z = 1 ; z <= 4 ; z++)
work[(k * 4) + z] = a[(k * 4) + z] ;
}
}
}
signed main() {
// freopen("cube.in" , "r" , stdin) ;
// freopen("cube.out" , "w" , stdout) ;
n = read() ;
for(qwq int i = 0 ; i < 6 ; i++)
for(qwq int x , j = 1 ; j <= 4 ; j++)
work[(i * 4) + j] = read() ;
if(n == 1) Solve() ;
else Dfs(1 , - 1) ;
return 0 ;
}