#include
using namespace std;
#define ll long long
#define endl "\n"
#define int ll
typedef unsigned long long ull;
typedef pair pll;
typedef pair pii;
//double 型memset最大127,最小128
//std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
const int INF = 0x3f3f3f3f; //int型的INF
const ll llINF = 0x3f3f3f3f3f3f3f3f;//ll型的llINF
const int N = 1e5 + 10;
int d[N];
int n,m;
int toit(int x)
{
int l=1,r=n,ans=INF,book=0;
while (l<=r)
{
int mid=l+((r-l)>>1);
if (abs(d[mid]-x)=x) r=mid-1;
else l=mid+1;
}
return d[book];
}
int32_t main()
{
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
cin>>t;
while (t--)
{
cin>>n>>m;
for (int i=1; i<=n; ++i)cin>>d[i];
sort(d+1,d+1+n);
d[0]=INF;
int a,b,c;
while (m--)
{
cin>>a>>b>>c;
int k=toit(b);
int tmp=(k-b)*(k-b)-4*a*c;
if (tmp<0)
{
cout<<"YES"<
显然,我们只需要知道每个点位处的路径最长可以多长就可以知道答案
学习过树的直径,我们知道2遍dfs可以确定树的最长直径。
如果我们把第二遍dfs搜出来的深度最深的点再来一遍dfs,可以求出每个点所属最长路径
#include
using namespace std;
#define ll long long
#define endl "\n"
#define int long long
#define endll endl< pii;
typedef pair pll;
//---------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------//
//double 型memset最大127,最小128
const int INF = 0x3f3f3f3f; //int型的INF
const ll llINF = 0x3f3f3f3f3f3f3f3f;//ll型的llINF
const int N = 1e5 + 10;
vectoredge[N];
void dfs(int u,int fa,vector&dep)
{
dep[u]=dep[fa]+1;
for (auto v:edge[u])if (v!=fa)dfs(v,u,dep);
}
void mysolve()
{
int n;
int u,v;
cin>>n;
for (int i=1; i>u>>v,edge[u].push_back(v),edge[v].push_back(u);
vectordep1(n+1),dep2(n+1);
dep1[0]=dep2[0]=-1;
dfs(1,0,dep1);
int a=max_element(dep1.begin()+1,dep1.end())-dep1.begin();
dfs(a,0,dep1);
int b=max_element(dep1.begin()+1,dep1.end())-dep1.begin();
dfs(b,0,dep2);//三遍dfs
vectord(n+1);
for (int i=1; i<=n; ++i)d[i]=max(dep1[i],dep2[i]);//每个点后两次的最深深度就是他们能处于的最长树径
sort(d.begin()+1,d.end());
int ans=1,p=1;
for (int i=1; i<=n; ++i)
{
while (ans> t;
while (t--)
{
mysolve();
}
system("pause");
return 0;
}
#include
using namespace std;
#define ll long long
#define endl "\n"
#define int long long
#define endll endl< pii;
typedef pair pll;
//---------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------//
//double 型memset最大127,最小128
const int INF = 0x3f3f3f3f; //int型的INF
const ll llINF = 0x3f3f3f3f3f3f3f3f;//ll型的llINF
const int N = 2e5 + 10;
setst1,st2;
unordered_mapcnt1,cnt2;
vectoredge[N];
pii b[N];
int a[N];
int ans1,ans2;
bool vis[N];
vectorpath,inpath;
bool dfs1(int u,int tar)//dfs求路径点与边
{
path.push_back(u);
vis[u]=1;
if (u==tar)return 1;
for (auto [v,in]:edge[u])
{
if (vis[v])continue;
inpath.push_back(in);
if (dfs1(v,tar))return 1;
inpath.pop_back();
}
path.pop_back();
return 0;
}
void todis(int u,int l,int r)//更新蓝色侵蚀部分
{
cnt1[a[u]]--,cnt2[a[u]]++;
if (cnt1[a[u]]<2)st1.erase(a[u]);
if (cnt2[a[u]]>1)st2.insert(a[u]);
for (auto [v,in]:edge[u])
{
if (v!=l&&v!=r)
{
todis(v,u,0);
}
}
}
int dis()//获取当前两个子树的最大M
{
int ans=0;
if (!st1.empty())ans=max(ans,*st1.rbegin());
if (!st2.empty())ans=max(ans,*st2.rbegin());
return ans;
}
void mysolve()
{
int n;
cin>>n;
int x,y;
for (int i=1; i>x>>y;
edge[x].push_back({y,i}),edge[y].push_back({x,i});//存储信息是对应的点及边的编号
}
for (int i=1; i<=n; ++i)
{
cin>>a[i];
cnt1[a[i]]++;
if (cnt1[a[i]]>1)st1.insert(a[i]);
}
if (st1.empty())for (int i=1; i2)for (int i=1; ians(n+1);
for (int i=1; ipoint;//记录x,y点
for (int i=1; i<=n; ++i)if (a[i]==*st1.rbegin())point.insert(i);
dfs1(*point.begin(),*point.rbegin());//找xy路径
todis(path[0],path[1],0);
ans[inpath[0]]=dis();
for (int i=1; i+1<(int)path.size(); ++i)
{
todis(path[i],path[i-1],path[i+1]);
ans[inpath[i]]=dis();
}
for (int i=1; i> t;
while (t--)
{
mysolve();
}
system("pause");
return 0;
}