250624 模拟赛
分数:\(40+10+28=78\)
感觉暴力没有打满,因为后面觉得大家 T1 肯定都过了所以开始自暴自弃哎哎哎。T3 很像昨天 jsy 说的某个东西,但是没有一直想感觉。
T1 愤怒之火
给你一棵树,构造一个长度为 \(n\) 的排列 \(p\),满足对于任意三个互不相同的节点 \(x,y,z\) 满足 \(y\) 在 \(x\leftrightarrow z\) 的最短路径上,\(p_y\)不在 \(p_x\leftrightarrow p_z\) 的路径上。 或报告无解。
对着这个题想了八百年,首先写了菊花的性质(\(p_1\) 不为 \(1\)),然后写了链的性质(\(n\ge5\) 无解,剩下两种情况复制样例然后瞎编一下,也可以理解是排列中不存在连续三个上升或者连续三个下降的)。感觉距离正解并不是非常远。中途交了一次随机打乱的,没有多得 \(1\) 分。
感觉有解的条件跟叶子数量或者直径有关,后面还是觉得前者比较对。但是感觉这个思路挺不对的,于是去想看能不能找到类似“不存在连续三个上升或者连续三个下降”的性质,然后对排列计数。开始想 dfs 序发现找不到。
考虑每个 \(y\),我们把它看作树根,然后经过它的路径怎么样,不经过它的路径怎么样,然后发现对于每个非叶节点,它的位置上放上一个叶子节点就是对的。
点击查看代码
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int t=0;char h=getchar();
while(!isdigit(h))h=getchar();
while(isdigit(h))t=(t<<1)+(t<<3)+(h^48),h=getchar();
return t;
}
void write(int x)
{
if(x>9)write(x/10);putchar(x%10+'0');
}
const int N=1e5+10;
int ind[N];
int n,x,y;
int st1[N],tp1,st2[N],tp2;
void solve()
{
n=read();memset(ind,0,(n+5)*sizeof(int));tp1=tp2=0;
for(int i=1;i<n;i++)x=read(),y=read(),++ind[x],++ind[y];
for(int i=1;i<=n;i++)if(ind[i]==1)st1[++tp1]=i;else st2[++tp2]=i;
if(tp1<tp2)
{
puts("No");return;
}
puts("Yes");
for(int i=1;i<=n;i++)if(ind[i]==1&&tp2)write(st2[tp2--]),putchar(' ');else write(st1[tp1--]),putchar(' ');
puts("");
}
int main()
{
freopen("fire.in","r",stdin);
freopen("fire.out","w",stdout);
int t=read();
while(t--)solve();
return 0;
}
T2 勾股计数
给定 \(n\) 计算有多少本质不同三元组 \((a,b,c)\) 满足:
- \(a,b,c\) 均为正整数。
- \(1\le a\le n\)
- \(a^2+b^2=c^2\)
一开始根本不知道这个题要干什么。发现找满足条件的 \(a^2=(c+b)(c-b)\)。要求 \(1\le a\le n\),\((c+b)\) 和 \((c-b)\) 奇偶性相同。
-
当 \(a\) 为奇数
显然所有 \(a^2\) 的因数对都可以贡献一次答案(除了 \(a\) 本身)。
-
当 \(a\) 为偶数
需要一个因数对中不但不能有 \(a\),而且需要两个数都是偶数,相当于 \(4 (\frac{a}{2})^2=2k\frac{2(\frac{a}{2})^2}{k}\),也就是 \((\frac{a}{2})^2=k\frac{(\frac{a}{2})^2}{k}\),只需找 \((\frac{a}{2})^2\) 的因数对数。
数学题然后疯狂推式子就没了。
T3 乱斗之星
因为所有路径的长度都可以表示为关于 \(T\) 的一次式,所以答案日期一定在 \({1,T_{max}}\) 中。
然后可以用一个类似于 bfs 的东西去算最短路,因为一个点所有的出边长度是相同的。
然后树就可以点分治之类的。
然后一般的就是根据每个关键点去做一遍点分治。
浙公网安备 33010602011771号