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) }
Codeforces Round 635 (Div.2)
吐槽环节
- 比赛就做出
4
4
4道,
D
f
s
t
D\ fst
D fst啦
- 中国场果真毒瘤
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.Ichihime and Triangle
题目意思
S
o
l
\mathrm{Sol}
Sol
-
s
h
a
b
b
y
shabby
shabby题目,因为是随便构造。所以我们只要强制两根长的木棒相等就可以了,保证满足条件的。
- 时间复杂度:
O
(
1
)
O(1)
O(1)
C
o
d
e
\mathrm{Code}
Code
#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.Kana and Dragon Quest game
题目意思
S
o
l
\mathrm{Sol}
Sol
- 又是简单题(
A
,
B
A,B
A,B两题共
6
6
6分钟就可以做完很正常。。。
- 我们就先不停地能使用操作
1
1
1就用直到
x
≤
10
x\leq 10
x≤10,我们再用操作
2
2
2。然后就判断这样过后剩余的
x
x
x与
0
0
0比一比就好了。
- 时间复杂度:
O
(
log
x
)
O(\log x)
O(logx)
C
o
d
e
\mathrm{Code}
Code
#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.Linova and Kingdom
题目意思
S
o
l
\mathrm{Sol}
Sol
- 一道简单的结论题目
- 那么选节点
x
x
x时,增加的答案
D
e
p
x
−
1
Dep_x-1
Depx−1,因为它成功变为了那个选择点节点,同时减少的答案为
S
i
z
x
−
1
Siz_x - 1
Sizx−1,因为它的子树节点都少了一个。
- 那么答案就是前
K
K
K大的
D
e
p
x
−
S
i
z
x
Dep_x-Siz_x
Depx−Sizx
- 时间复杂度:
O
(
n
log
n
)
O(n \log n)
O(nlogn)
C
o
d
e
\mathrm{Code}
Code
#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.Xenia and Colorful Gems
题目意思
S
o
l
\mathrm{Sol}
Sol
- 一道比较简单的题目,但是比赛时
f
s
t
fst
fst啦,赛后仔细想想开始想错了。
- 我们考虑一个简单的性质:就是如果选了
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∗nlogn),
k
k
k为常数
C
o
d
e
\mathrm{Code}
Code
#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.Kaavi and Magic Spell
题目意思
S
o
l
\mathrm{Sol}
Sol
- 一道区间
D
P
DP
DP题目
- 首先我们考虑如果那个串的长度已经大于
∣
T
∣
|T|
∣T∣,且前缀为
T
T
T后面就可以任意填了。
- 那么我们设
f
l
,
r
f_{l,r}
fl,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]
fl,r=fl,r+fl+1,r[Si=Tl]
-
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]
fl,r=fl,r+fl,r−1[Si=Tr]
- 对于
i
>
m
i>m
i>m的两个都可以转移
- 那么
a
n
s
=
∑
i
=
m
n
f
1
,
i
ans=\sum_{i=m}^{n} f_{1,i}
ans=∑i=mnf1,i
- 时间复杂度:
O
(
n
2
)
O(n^2)
O(n2)
C
o
d
e
\mathrm{Code}
Code
#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;
}