C
o
d
e
f
o
r
c
e
s
R
o
u
n
d
635
(
D
i
v
.
2
)
\mathrm{Codeforces\ Round \ 635 \ (Div. 2) }
C o d e f o r c e s R o u n d 6 3 5 ( D i v . 2 )
吐槽环节
比赛就做出
4
4
4 道,
D
f
s
t
D\ fst
D f s t 啦 中国场果真毒瘤
A
.
I
c
h
i
h
i
m
e
a
n
d
T
r
i
a
n
g
l
e
\mathrm{A.Ichihime\ and\ Triangle}
A . I c h i h i m e a n d T r i a n g l e
题目意思
S
o
l
\mathrm{Sol}
S o l
s
h
a
b
b
y
shabby
s h a b b y 题目,因为是随便构造。所以我们只要强制两根长的木棒相等就可以了,保证满足条件的。时间复杂度:
O
(
1
)
O(1)
O ( 1 )
C
o
d
e
\mathrm{Code}
C o d e
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
inline int read ( )
{
int sum= 0 , ff= 1 ; char ch= getchar ( ) ;
while ( ! isdigit ( ch) )
{
if ( ch== '-' ) ff= - 1 ;
ch= getchar ( ) ;
}
while ( isdigit ( ch) )
sum= sum* 10 + ( ch^ 48 ) , ch= getchar ( ) ;
return sum* ff;
}
int Q, a, b, c, d;
int main ( )
{
Q= read ( ) ;
for ( ; Q-- ; )
{
a= read ( ) ;
b= read ( ) ;
c= read ( ) ;
d= read ( ) ;
printf ( "%d %d %d\n" , b, c, c) ;
}
return 0 ;
}
B
.
K
a
n
a
a
n
d
D
r
a
g
o
n
Q
u
e
s
t
g
a
m
e
\mathrm{B.Kana\ and \ Dragon \ Quest \ game}
B . K a n a a n d D r a g o n Q u e s t g a m e
题目意思
S
o
l
\mathrm{Sol}
S o l
又是简单题(
A
,
B
A,B
A , B 两题共
6
6
6 分钟就可以做完很正常。。。 我们就先不停地能使用操作
1
1
1 就用直到
x
≤
10
x\leq 10
x ≤ 1 0 ,我们再用操作
2
2
2 。然后就判断这样过后剩余的
x
x
x 与
0
0
0 比一比就好了。 时间复杂度:
O
(
log
x
)
O(\log x)
O ( log x )
C
o
d
e
\mathrm{Code}
C o d e
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
inline int read ( )
{
int sum= 0 , ff= 1 ; char ch= getchar ( ) ;
while ( ! isdigit ( ch) )
{
if ( ch== '-' ) ff= - 1 ;
ch= getchar ( ) ;
}
while ( isdigit ( ch) )
sum= sum* 10 + ( ch^ 48 ) , ch= getchar ( ) ;
return sum* ff;
}
int Q, a, b, c, d;
int main ( )
{
Q= read ( ) ;
for ( ; Q-- ; )
{
a= read ( ) ;
b= read ( ) ;
c= read ( ) ;
while ( b> 0 && a> 10 )
{
a= a/ 2 + 10 ;
b-- ;
}
if ( a<= c* 10 ) puts ( "YES" ) ;
else puts ( "NO" ) ;
}
return 0 ;
}
C
.
L
i
n
o
v
a
a
n
d
K
i
n
g
d
o
m
\mathrm{C.Linova\ and \ Kingdom}
C . L i n o v a a n d K i n g d o m
题目意思
S
o
l
\mathrm{Sol}
S o l
一道简单的结论题目 那么选节点
x
x
x 时,增加的答案
D
e
p
x
−
1
Dep_x-1
D e p x − 1 ,因为它成功变为了那个选择点节点,同时减少的答案为
S
i
z
x
−
1
Siz_x - 1
S i z x − 1 ,因为它的子树节点都少了一个。 那么答案就是前
K
K
K 大的
D
e
p
x
−
S
i
z
x
Dep_x-Siz_x
D e p x − S i z x 时间复杂度:
O
(
n
log
n
)
O(n \log n)
O ( n log n )
C
o
d
e
\mathrm{Code}
C o d e
#include <bits/stdc++.h>
#define pb push_back
#define int long long
using namespace std;
inline int read ( )
{
int sum= 0 , ff= 1 ; char ch= getchar ( ) ;
while ( ! isdigit ( ch) )
{
if ( ch== '-' ) ff= - 1 ;
ch= getchar ( ) ;
}
while ( isdigit ( ch) )
sum= sum* 10 + ( ch^ 48 ) , ch= getchar ( ) ;
return sum* ff;
}
const int N= 2e5 + 5 ;
int n, m, dep[ N] , a[ N] , siz[ N] , ans;
vector< int > G[ N] ;
inline void dfs ( int u, int fa)
{
dep[ u] = dep[ fa] + 1 ;
siz[ u] = 1 ;
for ( int i= 0 ; i< G[ u] . size ( ) ; i++ )
{
int v= G[ u] [ i] ;
if ( v== fa) continue ;
dfs ( v, u) ;
siz[ u] + = siz[ v] ;
}
a[ u] = dep[ u] - siz[ u] ;
}
signed main ( )
{
n= read ( ) ;
m= read ( ) ;
for ( int i= 1 ; i< n; i++ )
{
int x, y;
x= read ( ) ;
y= read ( ) ;
G[ x] . pb ( y) ;
G[ y] . pb ( x) ;
}
dfs ( 1 , 0 ) ;
sort ( a+ 1 , a+ n+ 1 ) ;
reverse ( a+ 1 , a+ n+ 1 ) ;
for ( int i= 1 ; i<= m; i++ ) ans+ = a[ i] ;
printf ( "%lld\n" , ans) ;
return 0 ;
}
D
.
X
e
n
i
a
a
n
d
C
o
l
o
r
f
u
l
G
e
m
s
\mathrm{D.Xenia\ and \ Colorful\ Gems}
D . X e n i a a n d C o l o r f u l G e m s
题目意思
S
o
l
\mathrm{Sol}
S o l
一道比较简单的题目,但是比赛时
f
s
t
fst
f s t 啦,赛后仔细想想开始想错了。 我们考虑一个简单的性质:就是如果选了
A
A
A 中的一个球
x
x
x ,那么
B
,
C
B,C
B , C 中想让答案小是不是只要试图去接近他就可以了。然后
B
,
C
B,C
B , C 同理。 这样我们就对
A
,
B
,
C
A,B,C
A , B , C 各自做一遍。然后找到对应另外两个中与他接近的(具体地看代码吧 时间复杂度:
O
(
k
∗
n
log
n
)
O(k*n\log n)
O ( k ∗ n log n ) ,
k
k
k 为常数
C
o
d
e
\mathrm{Code}
C o d e
#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int read ( )
{
int sum= 0 , ff= 1 ; char ch= getchar ( ) ;
while ( ! isdigit ( ch) )
{
if ( ch== '-' ) ff= - 1 ;
ch= getchar ( ) ;
}
while ( isdigit ( ch) )
sum= sum* 10 + ( ch^ 48 ) , ch= getchar ( ) ;
return sum* ff;
}
const int N= 1e5 + 5 ;
int Q, na, nb, nc, ans;
int a[ N] , b[ N] , c[ N] ;
inline int Calc ( int x, int y, int z)
{
return ( x- y) * ( x- y) + ( z- x) * ( z- x) + ( y- z) * ( y- z) ;
}
signed main ( )
{
Q= read ( ) ;
for ( ; Q-- ; )
{
na= read ( ) , nb= read ( ) , nc= read ( ) ;
for ( int i= 1 ; i<= na; i++ ) a[ i] = read ( ) ;
for ( int i= 1 ; i<= nb; i++ ) b[ i] = read ( ) ;
for ( int i= 1 ; i<= nc; i++ ) c[ i] = read ( ) ;
sort ( a+ 1 , a+ na+ 1 ) ;
sort ( b+ 1 , b+ nb+ 1 ) ;
sort ( c+ 1 , c+ nc+ 1 ) ;
ans= 1e19 ;
for ( int i= 1 ; i<= na; i++ )
{
int pb= upper_bound ( b+ 1 , b+ nb+ 1 , a[ i] ) - b;
int pc= upper_bound ( c+ 1 , c+ nc+ 1 , a[ i] ) - c;
int pbb= pb- 1 , pcc= pc- 1 ;
if ( pb<= nb)
{
if ( pc<= nc) ans= min ( ans, Calc ( a[ i] , b[ pb] , c[ pc] ) ) ;
if ( pcc>= 1 ) ans= min ( ans, Calc ( a[ i] , b[ pb] , c[ pcc] ) ) ;
}
if ( pbb>= 1 )
{
if ( pc<= nc) ans= min ( ans, Calc ( a[ i] , b[ pbb] , c[ pc] ) ) ;
if ( pcc>= 1 ) ans= min ( ans, Calc ( a[ i] , b[ pbb] , c[ pcc] ) ) ;
}
}
for ( int i= 1 ; i<= nb; i++ )
{
int pa= upper_bound ( a+ 1 , a+ na+ 1 , b[ i] ) - a;
int pc= upper_bound ( c+ 1 , c+ nc+ 1 , b[ i] ) - c;
int paa= pa- 1 , pcc= pc- 1 ;
if ( pa<= na)
{
if ( pc<= nc) ans= min ( ans, Calc ( b[ i] , a[ pa] , c[ pc] ) ) ;
if ( pcc>= 1 ) ans= min ( ans, Calc ( b[ i] , a[ pa] , c[ pcc] ) ) ;
}
if ( paa>= 1 )
{
if ( pc<= nc) ans= min ( ans, Calc ( b[ i] , a[ paa] , c[ pc] ) ) ;
if ( pcc>= 1 ) ans= min ( ans, Calc ( b[ i] , a[ paa] , c[ pcc] ) ) ;
}
}
for ( int i= 1 ; i<= nc; i++ )
{
int pb= upper_bound ( b+ 1 , b+ nb+ 1 , c[ i] ) - b;
int pa= upper_bound ( a+ 1 , a+ na+ 1 , c[ i] ) - a;
int pbb= pb- 1 , paa= pa- 1 ;
if ( pb<= nb)
{
if ( pa<= na) ans= min ( ans, Calc ( c[ i] , b[ pb] , a[ pa] ) ) ;
if ( paa>= 1 ) ans= min ( ans, Calc ( c[ i] , b[ pb] , a[ paa] ) ) ;
}
if ( pbb>= 1 )
{
if ( pa<= na) ans= min ( ans, Calc ( c[ i] , b[ pbb] , a[ pa] ) ) ;
if ( paa>= 1 ) ans= min ( ans, Calc ( c[ i] , b[ pbb] , a[ paa] ) ) ;
}
}
printf ( "%lld\n" , ans) ;
}
return 0 ;
}
E
.
K
a
a
v
i
a
n
d
M
a
g
i
c
S
p
e
l
l
\mathrm{E.Kaavi\ and \ Magic \ Spell}
E . K a a v i a n d M a g i c S p e l l
题目意思
S
o
l
\mathrm{Sol}
S o l
一道区间
D
P
DP
D P 题目 首先我们考虑如果那个串的长度已经大于
∣
T
∣
|T|
∣ T ∣ ,且前缀为
T
T
T 后面就可以任意填了。 那么我们设
f
l
,
r
f_{l,r}
f l , r 表示填的那个串与
T
T
T 匹配了
[
l
,
r
]
[l,r]
[ l , r ] 的方案数 那么转移如下
f
l
,
r
=
f
l
,
r
+
f
l
+
1
,
r
[
S
i
=
T
l
]
f_{l,r}=f_{l,r}+f_{l+1,r} [S_i=T_l]
f l , r = f l , r + f l + 1 , r [ S i = T l ]
f
l
,
r
=
f
l
,
r
+
f
l
,
r
−
1
[
S
i
=
T
r
]
f_{l,r}=f_{l,r}+f_{l,r-1} [S_i=T_r]
f l , r = f l , r + f l , r − 1 [ S i = T r ] 对于
i
>
m
i>m
i > m 的两个都可以转移 那么
a
n
s
=
∑
i
=
m
n
f
1
,
i
ans=\sum_{i=m}^{n} f_{1,i}
a n s = ∑ i = m n f 1 , i 时间复杂度:
O
(
n
2
)
O(n^2)
O ( n 2 )
C
o
d
e
\mathrm{Code}
C o d e
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
inline int read ( )
{
int sum= 0 , ff= 1 ; char ch= getchar ( ) ;
while ( ! isdigit ( ch) )
{
if ( ch== '-' ) ff= - 1 ;
ch= getchar ( ) ;
}
while ( isdigit ( ch) )
sum= sum* 10 + ( ch^ 48 ) , ch= getchar ( ) ;
return sum* ff;
}
const int N= 3005 ;
const int mo= 998244353 ;
int n, m, f[ N] [ N] , ans;
char ch[ N] , th[ N] ;
int main ( )
{
scanf ( "%s" , ch+ 1 ) ;
scanf ( "%s" , th+ 1 ) ;
n= strlen ( ch+ 1 ) ;
m= strlen ( th+ 1 ) ;
for ( int i= 1 ; i<= n+ 1 ; i++ ) f[ i] [ i- 1 ] = 1 ;
for ( int i= 1 , len= 1 ; i<= n; i++ , len++ )
for ( int l= 1 , r= l+ len- 1 ; r<= n; l++ , r++ )
{
if ( l> m|| ch[ i] == th[ l] )
f[ l] [ r] = ( f[ l] [ r] + f[ l+ 1 ] [ r] ) % mo;
if ( r> m|| ch[ i] == th[ r] )
f[ l] [ r] = ( f[ l] [ r] + f[ l] [ r- 1 ] ) % mo;
}
for ( int i= m; i<= n; i++ ) ans= ( ans+ f[ 1 ] [ i] ) % mo;
printf ( "%d\n" , ans) ;
return 0 ;
}