牛客多校第六场个人补题B G J M
B
题意
给定一棵有根树,每个节点可以为它的 0 ~ 𝑑[𝑖] 级祖先贡献 1 的价值。求最终每个点的价值。
思路
赛时想的就是树上倍增,用lca的倍增预处理思想,然后对吗,每个结点向上求范围,进行差分,最后根据拓补序进行还原答案就可以了(貌似也可以处理一下dfs序,求前缀和,这样就省去了拓补排序的过程)
代码
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 5;
const double eps = 1e-9;
typedef pair<int, int> PII;
vector<int> g[N];
int dp[N][22];
int d[N];
int df[N];
int deep[N];
int de[N];
void dfs(int u, int f, int d){
deep[u] = d;
for(int i = 1;(1 << i) < deep[u];i++){
dp[u][i] = dp[dp[u][i - 1]][i - 1];
}
for(int v:g[u]){
if(v != f){
dp[v][0] = u;
dfs(v, u, d + 1);
}
}
}
int findf(int u, int dis){
int k = log2(dis);
int t = 0;
int ret = u;
for(int i = k;i >= 0;i--){
if(t + (1 << i) <= dis){
t += (1 << i);
ret = dp[ret][i];
}
}
return ret;
}
void dfs2(int u, int f){
df[u] += df[f];
for(int v:g[u]){
if(v != f){
dfs2(v, u);
}
}
}
void solve(){
int n;
scanf("%lld", &n);
for(int i = 0;i < n - 1;i++){
int u, v;
scanf("%lld%lld", &u, &v);
g[u].push_back(v);
g[v].push_back(u);
de[u]++;
de[v]++;
}
de[1]++;
for(int i = 1;i <= n;i++){
scanf("%lld", &d[i]);
}
dfs(1, 0, 1);
for(int i = 1;i <= n;i++){
int u = findf(i, d[i] + 1);
df[i]++;
df[u]--;
}
vector<int> pat;
queue<int> q;
for(int i = 1;i <= n;i++){
if(de[i] == 1){
q.push(i);
de[i]--;
}
}
while(q.size()){
int u = q.front();
pat.push_back(u);
q.pop();
for(int v:g[u]){
de[v]--;
if(de[v] == 1){
q.push(v);
}
}
}
for(int i:pat){
for(int v:g[i]){
if(deep[v] > deep[i]){
df[i] += df[v];
}
}
}
for(int i = 1;i <= n;i++){
printf("%lld ", df[i]);
}
}
signed main() {
// IOS;
int T = 1;
cin >> T;
while (T--) {
solve();
}
}
G
题意
输出给定尺寸的图形
思路
比赛的时候懒得模拟嫌麻烦,看只有5的数据直接暴力画的。。。
代码
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 5;
const double eps = 1e-9;
typedef pair<int, int> PII;
string x1[9] = {"********************************",
"*..............................*",
"*..@...@..@@@@@..@......@@@@@..*",
"*..@@..@..@......@......@......*",
"*..@.@.@..@@@@@..@......@@@@@..*",
"*..@..@@..@......@..........@..*",
"*..@...@..@......@@@@@..@@@@@..*",
"*..............................*",
"********************************"
};
string x2[13] = {"*********************************************",
"*...........................................*",
"*...........................................*",
"*...@.....@...@@@@@@@...@.........@@@@@@@...*",
"*...@@....@...@.........@.........@.........*",
"*...@.@...@...@.........@.........@.........*",
"*...@..@..@...@@@@@@@...@.........@@@@@@@...*",
"*...@...@.@...@.........@...............@...*",
"*...@....@@...@.........@...............@...*",
"*...@.....@...@.........@@@@@@@...@@@@@@@...*",
"*...........................................*",
"*...........................................*",
"*********************************************"
};
string x3[17] = {"**********************************************************",
"*........................................................*",
"*........................................................*",
"*........................................................*",
"*....@.......@....@@@@@@@@@....@............@@@@@@@@@....*",
"*....@@......@....@............@............@............*",
"*....@.@.....@....@............@............@............*",
"*....@..@....@....@............@............@............*",
"*....@...@...@....@@@@@@@@@....@............@@@@@@@@@....*",
"*....@....@..@....@............@....................@....*",
"*....@.....@.@....@............@....................@....*",
"*....@......@@....@............@....................@....*",
"*....@.......@....@............@@@@@@@@@....@@@@@@@@@....*",
"*........................................................*",
"*........................................................*",
"*........................................................*",
"**********************************************************"
};
string x4[21] = {"***********************************************************************",
"*.....................................................................*",
"*.....................................................................*",
"*.....................................................................*",
"*.....................................................................*",
"*.....@.........@.....@@@@@@@@@@@.....@...............@@@@@@@@@@@.....*",
"*.....@@........@.....@...............@...............@...............*",
"*.....@.@.......@.....@...............@...............@...............*",
"*.....@..@......@.....@...............@...............@...............*",
"*.....@...@.....@.....@...............@...............@...............*",
"*.....@....@....@.....@@@@@@@@@@@.....@...............@@@@@@@@@@@.....*",
"*.....@.....@...@.....@...............@.........................@.....*",
"*.....@......@..@.....@...............@.........................@.....*",
"*.....@.......@.@.....@...............@.........................@.....*",
"*.....@........@@.....@...............@.........................@.....*",
"*.....@.........@.....@...............@@@@@@@@@@@.....@@@@@@@@@@@.....*",
"*.....................................................................*",
"*.....................................................................*",
"*.....................................................................*",
"*.....................................................................*",
"***********************************************************************"
};
string x5[25] = {"************************************************************************************",
"*..................................................................................*",
"*..................................................................................*",
"*..................................................................................*",
"*..................................................................................*",
"*..................................................................................*",
"*......@...........@......@@@@@@@@@@@@@......@..................@@@@@@@@@@@@@......*",
"*......@@..........@......@..................@..................@..................*",
"*......@.@.........@......@..................@..................@..................*",
"*......@..@........@......@..................@..................@..................*",
"*......@...@.......@......@..................@..................@..................*",
"*......@....@......@......@..................@..................@..................*",
"*......@.....@.....@......@@@@@@@@@@@@@......@..................@@@@@@@@@@@@@......*",
"*......@......@....@......@..................@..............................@......*",
"*......@.......@...@......@..................@..............................@......*",
"*......@........@..@......@..................@..............................@......*",
"*......@.........@.@......@..................@..............................@......*",
"*......@..........@@......@..................@..............................@......*",
"*......@...........@......@..................@@@@@@@@@@@@@......@@@@@@@@@@@@@......*",
"*..................................................................................*",
"*..................................................................................*",
"*..................................................................................*",
"*..................................................................................*",
"*..................................................................................*",
"************************************************************************************"
};
void solve() {
int n;
cin >> n;
if(n==1) {
for(int i=0;i<4*n+5;i++) {
cout<<x1[i]<<endl;
}
}
else if(n==2) {
for(int i=0;i<4*n+5;i++) {
cout<<x2[i]<<endl;
}
}
else if(n==3) {
for(int i=0;i<4*n+5;i++) {
cout<<x3[i]<<endl;
}
}
else if(n==4) {
for(int i=0;i<4*n+5;i++) {
cout<<x4[i]<<endl;
}
}
else if(n==5) {
for(int i=0;i<4*n+5;i++) {
cout<<x5[i]<<endl;
}
}
}
signed main() {
IOS;
int T = 1;
// cin >> T;
while (T--) {
solve();
}
}
J
题意
给a,b,c,x,已知b可以变换成a-b,c可以变换成b-c,问变换若干次c能否变成x
思路
先想的有问题,以为是就只有四个值,结果又画了画发现就是判断对于三个基础值c,b-c,a-b-c能否通过乘以k倍a-2b变成x
代码
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 5;
const double eps = 1e-9;
typedef pair<int, int> PII;
int a[N];
void solve() {
int a,b,c,x;
cin>>a>>b>>c>>x;
int x1=c,x2=b-c,x3=a-b-c;
int d=a-2*b;
if(d==0) {
if(x1!=x&&x2!=x&&x3!=x) {
cout<<"No\n";
}
else {
cout<<"Yes\n";
}
}
else if((x1-x)%d==0) {
cout<<"Yes\n";
}
else if((x2-x)%d==0) {
cout<<"Yes\n";
}
else if((x3-x)%d==0) {
cout<<"Yes\n";
}
else cout<<"No\n";
}
signed main() {
IOS;
int T = 1;
cin >> T;
while (T--) {
solve();
}
}
M
题意
两个人在 N∗M 的网格上轮流移动一个棋子。棋子初始位为 (1,1) ,每次只能向某一维的正方向移动一格。网格上有一些特殊点,移到标 ’A’ 的点先手胜,移到标 ‘B’ 的点先手败,没有移到特殊点且不能再移动棋子则为平局。问先手是否有必胜、必平局、必败的策略。
思路
比赛的时候以为是个博弈,结果就陷进去了,看题解才发现是一个dp,唯一要注意的是对于步数的奇偶性来判断是谁走,是否能够到达目标点位。
代码
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 5;
const double eps = 1e-9;
typedef pair<int, int> PII;
char a[510][510];
int g[510][510];
int f[510][510];
void check(int n, int m, char w) {
int i, j;
for (i = 1; i <= n + 1; i++) {
for (j = 1; j <= m + 1; j++) {
if (a[i][j] == w) g[i][j] = 1;
else if (a[i][j] != '.' && a[i][j] != '\0') g[i][j] = 2;
else g[i][j] = 0;
f[i][j] = 0;
}
}
for (i = n; i > 0; i--) {
for (j = m ; j > 0; j--) {
int step = (i + j) & 1;
if (g[i][j] == 1) {
if (!step) f[i][j] = 1;
else f[i][j] = 0;
} else if (g[i][j] == 2) {
if (!step) f[i][j] = 0;
else f[i][j] = 1;
} else {
if (i < n && f[i + 1][j] == 0) f[i][j] = 1;
if (j < m && f[i][j + 1] == 0) f[i][j] = 1;
}
}
}
// for(int i = 1;i <= n;i++) {
// for(int j = 1;j <= m;j++) {
// cout<<g[i][j]<<' ';
// }
// cout<<endl;
// }
if (f[1][1] == 1) {
printf("yes");
} else {
printf("no");
}
}
void solve() {
int n, m;
cin >> n >> m;
memset(a, '\0', sizeof a);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> a[i][j];
}
}
if (a[n][m] == '.') a[n][m] = 'D';
check(n, m, 'A');
cout << ' ';
check(n, m, 'D');
cout << ' ';
check(n, m, 'B');
cout << '\n';
}
signed main() {
// IOS;
int T = 1;
cin >> T;
while (T--) {
solve();
}
}