我这份代码已经奇怪到一定程度了~
洛谷上一直 $TLE$,但是本地造了几个数据都过了.
// luogu-judger-enable-o2
#include <bits/stdc++.h>
#define N 1000005
#define inf 100001
#define setIO(s) freopen(s".in","r",stdin) , freopen(s".out","w",stdout)
using namespace std;
char *p1,*p2,buf[100000];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int rd() {int x=0; char c=nc(); while(c<48) c=nc(); while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc(); return x;}
int edges,n,flag;
int hd[N],to[N<<1],nex[N<<1],val[N],rt[N<<2];
void add(int u,int v)
{
nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;
}
namespace segin
{
#define lson t[x].ls
#define rson t[x].rs
int tot;
struct Node
{
int ls,rs,sum;
}t[N*100];
void update(int &x,int l,int r,int p,int v)
{
if(!x) x=++tot;
t[x].sum+=v;
if(l==r) return;
int mid=(l+r)>>1;
if(p<=mid) update(lson,l,mid,p,v);
else update(rson,mid+1,r,p,v);
}
int query(int x,int l,int r,int L,int R)
{
if(!x) return 0;
if(l>=L&&r<=R) return t[x].sum;
int mid=(l+r)>>1,re=0;
if(L<=mid) re+=query(lson,l,mid,L,R);
if(R>mid) re+=query(rson,mid+1,r,L,R);
return re;
}
void re()
{
for(int i=1;i<=tot;++i)
t[i].ls=t[i].rs=t[i].sum=0;
tot=0;
}
#undef lson
#undef rson
};
namespace segout
{
#define lson (now<<1)
#define rson (now<<1|1)
vector<int>g;
int vis[N*100];
void update(int l,int r,int now,int x,int y,int v)
{
segin::update(rt[now],0,n,y,v);
if(!vis[now]) vis[now]=1, g.push_back(now);
if(l==r) return;
int mid=(l+r)>>1;
if(x<=mid) update(l,mid,lson,x,y,v);
else update(mid+1,r,rson,x,y,v);
}
int query(int l,int r,int now,int L,int R,int L2,int R2)
{
if(l>=L&&r<=R)
return segin::query(rt[now],0,n,L2,R2);
int mid=(l+r)>>1,re=0;
if(L<=mid) re+=query(l,mid,lson,L,R,L2,R2);
if(R>mid) re+=query(mid+1,r,rson,L,R,L2,R2);
return re;
}
void re()
{
for(int i=0;i<g.size();++i)
vis[g[i]]=rt[g[i]]=0;
g.clear();
}
#undef lson
#undef rson
};
struct Node
{
int l,r,x;
Node(int l=0,int r=0,int x=0):l(l),r(r),x(x){}
};
vector<Node>e[N];
struct Point
{
int l,r,id,val;
Point(int l=0,int r=0,int id=0,int val=0):l(l),r(r),id(id),val(val){}
};
vector<Point>F[N];
bool cmp(Point a,Point b)
{
return a.l==b.l?a.id>b.id:a.l>b.l;
}
int root,sn;
int mx[N],size[N],vis[N],Fa[N],answer[N],lsty[N],lstx[N];
void dfs(int u,int ff)
{
size[u]=1;
for(int i=hd[u];i;i=nex[i])
if(to[i]!=ff&&!vis[to[i]])
dfs(to[i],u),size[u]+=size[to[i]];
}
void getroot(int u,int ff)
{
size[u]=1,mx[u]=0;
for(int i=hd[u];i;i=nex[i])
if(to[i]!=ff&&!vis[to[i]])
getroot(to[i],u),size[u]+=size[to[i]],mx[u]=max(mx[u],size[to[i]]);
mx[u]=max(mx[u],sn-size[u]);
if(mx[u]<mx[root]) root=u;
}
void calc(int u,int ff,int Min,int Max,int rt)
{
Min=min(Min,u),Max=max(Max,u);
F[rt].push_back(Point(Min,Max,u,val[u])), e[u].push_back(Node(Min,Max,rt));
for(int i=hd[u];i;i=nex[i])
if(!vis[to[i]]&&to[i]!=ff)
calc(to[i],u,Min,Max,rt);
}
void prepare(int u)
{
vis[u]=1;
calc(u,0,u,u,u);
for(int i=hd[u];i;i=nex[i])
if(!vis[to[i]])
dfs(to[i],u),sn=size[to[i]],root=0,getroot(to[i],u),Fa[root]=u,prepare(root);
}
void Push(int u,int l,int r,int id)
{
for(int i=0;i<(int)e[u].size();++i)
{
if(e[u][i].l>=l&&e[u][i].r<=r)
{
F[e[u][i].x].push_back(Point(l,r,-1,id));
break;
}
}
}
void solve(int u)
{
int i,j;
sort(F[u].begin(),F[u].end(),cmp);
for(i=0;i<(int)F[u].size();++i)
{
Point p=F[u][i];
if(p.id==-1)
answer[p.val]=segout::query(0,n,1,p.l,p.r,p.l,p.r);
else
{
if(!lsty[p.val]||p.r<=lsty[p.val])
{
if(lsty[p.val]) segout::update(0,n,1,lstx[p.val],lsty[p.val],-1);
segout::update(0,n,1,p.l,p.r,1);
lstx[p.val]=p.l, lsty[p.val]=p.r;
}
}
}
for(i=0;i<(int)F[u].size();++i)
if(F[u][i].id!=-1)
lstx[F[u][i].val]=lsty[F[u][i].val]=0;
segin::re();
segout::re();
}
int main()
{
int i,j,m;
// setIO("input");
n=rd(),m=rd();
for(i=1;i<=n;++i) val[i]=rd();
for(i=1;i<n;++i)
{
int x,y;
x=rd(),y=rd(),add(x,y),add(y,x);
}
root=0,mx[0]=sn=n,getroot(1,0),prepare(root);
for(i=1;i<=m;++i)
{
int l,r,x;
l=rd(),r=rd(),x=rd(),Push(x,l,r,i);
}
for(i=1;i<=n;++i) if(F[i].size()) solve(i);
for(i=1;i<=m;++i) printf("%d\n",answer[i]);
return 0;
}