# Codeforces Round #635 (Div. 1)

## A. Linova and Kingdom (CF 1336 A)

### 解题思路

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
template <typename T>
int s = 0, c = getchar();
x = 0;
while (isspace(c)) c = getchar();
if (c == 45) s = 1, c = getchar();
while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
if (s) x = -x;
}

template <typename T>
void write(T x, char c = ' ') {
int b[40], l = 0;
if (x < 0) putchar(45), x = -x;
while (x > 0) b[l++] = x % 10, x /= 10;
if (!l) putchar(48);
while (l) putchar(b[--l] | 48);
putchar(c);
}

void DFS(int u,int fa,int deep[],int son[],vector<int> edge[]){
for(auto v:edge[u]){
if (v==fa) continue;
deep[v]=deep[u]+1;
++son[u];
DFS(v,u,deep,son,edge);
son[u]+=son[v];
}
}

int main(void) {
int n,k;
vector<int> edge[n+1];
for(int u,v,i=1;i<n;++i){
edge[u].push_back(v);
edge[v].push_back(u);
}
int deep[n+1]={0};
int son[n+1]={0};
DFS(1,1,deep,son,edge);
vector<int> val;
for(int i=1;i<=n;++i){
val.push_back(son[i]-deep[i]);
}
sort(val.begin(),val.end(),greater<int>());
LL ans=0;
for(int i=0;i<n-k;++i) ans+=(LL)val[i];
write(ans,'\n');
return 0;
}

## B. Xenia and Colorful Gems (CF 1336 B)

### 解题思路

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
template <typename T>
int s = 0, c = getchar();
x = 0;
while (isspace(c)) c = getchar();
if (c == 45) s = 1, c = getchar();
while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
if (s) x = -x;
}

template <typename T>
void write(T x, char c = ' ') {
int b[40], l = 0;
if (x < 0) putchar(45), x = -x;
while (x > 0) b[l++] = x % 10, x /= 10;
if (!l) putchar(48);
while (l) putchar(b[--l] | 48);
putchar(c);
}

LL cal(LL a,LL b,LL c){
return (a-b)*(a-b)+(a-c)*(a-c)+(b-c)*(b-c);
}

void work(vector<LL> num[],int a,int b,int c,LL &ans){
for(auto i:num[a]){
auto l=upper_bound(num[b].begin(),num[b].end(),i);
if (l==num[b].begin()) continue;
--l;
auto r=lower_bound(num[c].begin(),num[c].end(),i);
if (r==num[c].end()) continue;
ans=ans==-1?cal(i,*l,*r):min(ans,cal(i,*l,*r));
}
}

int main(void) {
int t;
while(t--){
LL ans=-1;
int cnt[3]={0};
vector<LL> num[3];
for(int i=0;i<3;++i){
for(int u,j=0;j<cnt[i];++j){
num[i].push_back((LL)u);
}
sort(num[i].begin(),num[i].end());
}
work(num,0,1,2,ans);
work(num,0,2,1,ans);
work(num,1,0,2,ans);
work(num,1,2,0,ans);
work(num,2,0,1,ans);
work(num,2,1,0,ans);
write(ans,'\n');
}
return 0;
}

## C. Kaavi and Magic Spell (CF 1336 C)

### 题目大意

• $S$的首字符放到$A$的首部
• $S$的首字符放到$A$的尾部

### 解题思路

$dp[l][r]$表示构造串$A$$[l...r)$(从$0$开始)的所有方法中，满足串$A$是膜法的方法的数量。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

const LL mo=998244353;

char s[3006],t[3006];

int ls,lt;

LL dp[3006][3006];

LL ans;

LL DP(int pos,int l,int r,int id,int cntt){
if (l==r) {
ans=(ans+min(id,ls-lt))%mo;;
return 1;
}
if (dp[l][r]!=-1) {
ans=(ans+dp[l][r]*min(id,ls-lt))%mo;
return dp[l][r];
}
LL qwq=0;
if (l>lt-1||s[pos]==t[l]) qwq=(qwq+DP(pos-1,l+1,r,id==12345?cntt:id,cntt+1))%mo;
if (r>lt||s[pos]==t[r-1]) qwq=(qwq+DP(pos-1,l,r-1,id,cntt+1))%mo;
return dp[l][r]=qwq;
}

int main(void) {
scanf("%s%s",s,t);
memset(dp,-1,sizeof(dp));
ls=strlen(s);
lt=strlen(t);
ans=(ans+DP(ls-1,0,ls,12345,0))%mo;
LL qwq=0;
for(int i=lt;i<=ls;++i)
qwq=(qwq+dp[0][i])%mo;
printf("%lld\n",qwq);
return 0;
}

$tourist翻了($

posted @ 2020-04-16 17:01  ~Lanly~  阅读(181)  评论(0编辑  收藏