XJ疫情邀请赛
Isshiki_Hugh · · 个人记录
传送门
中文题面
虽然没有参加比赛(其实是报名的时候遇到小问题最后因为懒所以就没参加
但还是打算把题补补上
<!-- more -->
A.核酸检测
看看时间差不多就该心领神会了。
考虑构造线路,DNA形排列。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<cstdlib>//rand()
#define rep(i,a,b) for(register int i = (a);i <= (b);++i)
#define per(i,a,b) for(register int i = (a);i >= (b);--i)
typedef long long ll;
typedef unsigned long long ull;
using std::string;using std::cin;using std::cout;
int n,t,now;
int main(){
cin >> n;
if(n & 1){ // 奇数行
t = (n - 1) / 2 , now = n;
cout << (n * n + n) - 1 << "\n";
while(t--){
rep(i,1,n + 1) cout << now + (i & 1) - 1 << " " << i << "\n";
per(i,n + 1,1) cout << now + (!(i & 1)) - 1 << " " << i << "\n";
now -= 2;
}
rep(i,1,n + 1) cout << 1 << " " << i << "\n";
} else { // 偶数行
t = n / 2 , now = 1;
cout << (n * n + n) - 1 << "\n";
while(t--){
rep(i,1,n) cout << i << " " << now + (!(i & 1)) << "\n";
per(i,n,1) cout << i << " " << now + (i & 1) << "\n";
now += 2;
}
rep(i,1,n) cout << i << " " << n + 1 << "\n";
}
return 0;
}
B.齐心抗疫
寻找树的直径端点,答案存在于端点到任意点的连线中。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<cstdlib>//rand()
#define rep(i,a,b) for(register long long i = (a);i <= (b);++i)
#define per(i,a,b) for(register long long i = (a);i >= (b);--i)
typedef long long ll;
typedef unsigned long long ull;
using std::string;using std::cin;using std::cout;
ll n,a[55555],u,v,dis,ans;
ll next[111111],ver[111111],head[111111],tot;
inline void link(ll x,ll y){
ver[++tot] = y , next[tot] = head[x] , head[x] = tot;
}
inline void dfs(ll now,ll father,ll depth){
if(depth > dis) dis = depth , u = now;
for(register int i = head[now];i;i = next[i]){
if(ver[i] != father) dfs(ver[i],now,depth+1);
}
}
inline void find(){
dfs(1,0,0);
dis = 0 , v = u;
dfs(v,0,0);
}
inline void update(ll now,ll father,ll depth){
ll sum = depth * std::max(a[u],a[now]);
ans = std::max(sum,ans);
for(register int i = head[now];i;i = next[i]){
if(ver[i] != father) update(ver[i],now,depth+1);
}
}
int main(){
cin >> n;
rep(i,1,n) cin >> a[i];
rep(i,1,n-1){
cin >> u >> v;
link(u,v) , link(v,u);
}
find();
update(u,0,0);
std::swap(u,v);
update(u,0,0);
cout << ans << "\n";
return 0;
}