= =两个月不学习的fw这两个月来写的第一个题..
简单的来说就是树状数组硬搞...
首先在假如温度区间不在这个范围的点,先做个标记,就不用往上跳,且下面的点也一定不行..
然后就简单的倍增因为符合单调性就跳,跳到最高点然后判断子树中合法的.
简单的说就是在这个温度区间的,然后因为不涉及修改操作,可以树状数组离线按权值排序,左右端点的权值先分开再整合..然后离散化一下dfs序一下就可以通过这个题目了.\
code:
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5,M=20;
vector<int>G[N<<2];
int ls[N<<2],id,t[N<<2],x[N<<2],L[N<<2],R[N<<2],c[N<<2],n,num;
int bit(int u)
{
return u&(-u);
}
void add(int u)
{
while(u<=num)
{
c[u]++;
u+=bit(u);
}
}
int qry(int u)
{
int res=0;
while(u)
{
res+=c[u];
u-=bit(u);
}
return res;
}
int f[N][M],sz[N],idx,S[N];
struct Qry{
int l,r,wl,wr,id;
}Q[N];
struct cs{
int w,id;
}a[N];
bool cnp(cs A,cs B)
{
return A.w<B.w;
}
bool Ans(Qry A,Qry B)
{
return A.id<B.id;
}
struct Res{
int w,l,r,id,op,ans,f;
}ask[N<<2];
bool cmmp(Res A,Res B)
{
return A.w<B.w;
}
bool cnnp(Res A,Res B)
{
if(A.id==B.id) return A.op>B.op;
else return A.id<B.id;
}
void init(int u,int fa)
{
f[u][0]=fa;sz[u]=1;S[u]=++idx;
for(int i=1;i<=19;i++)
f[u][i]=f[f[u][i-1]][i-1];
for(int v:G[u])
{
if(v==fa) continue;
init(v,u);
sz[u]+=sz[v];
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
for(int i=1;i<=n;i++)
{
scanf("%d",&t[i]);
ls[++id]=t[i];
}
int q;
scanf("%d",&q);
for(int i=1;i<=q;i++)
{
scanf("%d%d%d",&x[i],&L[i],&R[i]);
ls[++id]=L[i];
ls[++id]=R[i];
}
sort(ls+1,ls+1+id);
num=unique(ls+1,ls+1+id)-ls-1;
for(int i=1;i<=n;i++)
{
t[i]=lower_bound(ls+1,ls+1+num,t[i])-ls;
a[i].w=t[i];
a[i].id=i;
}
for(int i=1;i<=q;i++)
{
L[i]=lower_bound(ls+1,ls+1+num,L[i])-ls;
R[i]=lower_bound(ls+1,ls+1+num,R[i])-ls;
}
t[0]=1e9;
init(1,0);
int dd=0;
for(int i=1;i<=q;i++)
{
bool fl=false;
//找到每个点的节点在哪.
int u=x[i];
Q[i].id=i;
Q[i].wl=L[i];
Q[i].wr=R[i];
if(t[u]>R[i]||t[u]<L[i]) fl=true;
for(int j=19;j>=0;j--)
{
if(t[f[u][j]]<=R[i]) u=f[u][j];
}
Q[i].l=S[u];
Q[i].r=S[u]+sz[u]-1;
ask[++dd].id=i;
ask[dd].op=0;
ask[dd].l=Q[i].l;
ask[dd].r=Q[i].r;
ask[dd].w=L[i]-1;
if(fl) ask[dd].f=1;
else ask[dd].f=0;
ask[++dd].id=i;
ask[dd].op=1;
ask[dd].l=Q[i].l;
ask[dd].r=Q[i].r;
ask[dd].w=R[i];
if(fl) ask[dd].f=1;
else ask[dd].f=0;
}
sort(a+1,a+1+n,cnp);
sort(ask+1,ask+1+dd,cmmp);
int l=1;
for(int i=1;i<=dd;i++)
{
while(l<=n&&a[l].w<=ask[i].w) add(S[a[l].id]),l++;
if(ask[i].f) ask[i].ans=0;
else ask[i].ans=qry(ask[i].r)-qry(ask[i].l-1);
}
sort(ask+1,ask+1+dd,cnnp);
for(int i=1;i<=dd;i+=2)
{
printf("%d\n",ask[i].ans-ask[i+1].ans);
}
return 0;
}

京公网安备 11010502036488号