难受,翻了各种傻逼错误,导致现在才改完
(函数没return,样例忘了换行,多余输出忘了删,估计是太晚了,脑子已经瓦特了)
,,,,
昨天是2018WF 莫斯科拿了一个冠军一个亚军,北大主场拿了季军。
这是一个树链剖分裸题,但是以前没看过,还比较简单,
来几个博客
;此题借鉴点击打开链接
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = 1e5+7;
vector<int> eg[maxn];
int top[maxn];
int siz[maxn];
int son[maxn];
int tid[maxn];
int ran[maxn];
int dep[maxn];
int fa[maxn];
int cnt,n;
long long val[maxn];
long long s[maxn];
long long tree[maxn*4],mx[maxn*4],mn[maxn*4];
void init()
{
memset(son,-1,sizeof(son));
memset(siz,0,sizeof(siz));
memset(fa,0,sizeof(fa));
memset(tid,0,sizeof(tid));
}
void dfs1(int u,int f,int d)
{
//cout<<".."<<u<<endl;
dep[u]=d;
siz[u]=1;
fa[u]=f;
for(int i=0;i<eg[u].size();i++)
{
int v=eg[u][i];
if(v==f)
continue;
if(!siz[v])
{
dfs1(v,u,d+1);
siz[u]+=siz[v];
if(son[u]==-1||siz[v]>siz[son[u]])
{
son[u]=v;
}
}
}
}
void dfs2(int u,int tp)
{
//cout<<u<<endl;
top[u]=tp;
tid[u]=++cnt;
if(son[u]!=-1)
dfs2(son[u],tp);
for(int i=0;i<eg[u].size();i++)
{
int v=eg[u][i];
if(v==fa[u]||son[u]==v) continue;
if(!tid[v])
dfs2(v,v);
}
}
void gettree()
{
dfs1(1,0,0);
cnt=0;
dfs2(1,1);
for(int i=1;i<=n;i++)
{
// cout<<tid[i]<<" "<<top[i]<<" "<<son[i]<<endl;
val[tid[i]]=s[i];
}
// cout<<"--"<<endl;
}
void build(int root,int l,int r)
{
if(l==r)
{
tree[root]=mx[root]=mn[root]=val[l];
return;
}
int mid=(l+r)>>1;
build(root*2,l,mid);
build(root*2+1,mid+1,r);
tree[root]=tree[root*2]+tree[root*2+1];
mx[root]=max(mx[root*2],mx[root*2+1]);
mn[root]=min(mn[root*2],mn[root*2+1]);
}
long long query(int root,int l,int r,int ql,int qr,long long a,long long b)
{
// if(ql>r||qr<l)
// return 0;
if(ql<=l&&qr>=r)
{
//if(mn[root]>b||mx[root]<a)
// return 0;
if(mn[root]>b||mx[root]<a)
return 0; //还有半个的情况
if(mx[root]<=b&&mn[root]>=a)
return tree[root];
}
int mid=(l+r)>>1;
long long ans=0;
if(ql<=mid)
ans+=query(root*2,l,mid,ql,qr,a,b);
if(qr>mid)
ans+=query(root*2+1,mid+1,r,ql,qr,a,b);
//cout<<ans<<endl;
return ans;
}
long long solve(int u,int v,long long a,long long b)
{
int top1=top[u],top2=top[v];
long long ans=0;
while(top1!=top2)
{
if(dep[top1]<dep[top2])
{
swap(top1,top2);
swap(u,v);
}
// cout<<u<<v<<endl;
ans+=query(1,1,n,tid[top1],tid[u],a,b);
u=fa[top1];
top1=top[u];
}
if(u==v)
{
//cout<<"."<<u<<endl;
if(s[u]>=a&&s[u]<=b)
ans+=s[u];
//cout<<","<<ans<<endl;
return ans;
}
if(dep[u]>dep[v])
swap(u,v); //cout<<","<<ans<<" "<<tid[u]<<" "<<tid[v]<<endl;
ans+=query(1,1,n,tid[u],tid[v],a,b);
return ans;
}
int main()
{
int m;
while(~scanf("%d%d",&n,&m))
{
cnt=0;
init();
for(int i=0;i<=n;i++)
{
eg[i].clear();
}
for(int i=1; i<=n; i++)
{
scanf("%lld",&s[i]);
}
for(int i=0; i<n-1; i++)
{
int x,y;
scanf("%d%d",&x,&y);
eg[x].push_back(y);
eg[y].push_back(x);
}
gettree();
build(1,1,n);
for(int i=0;i<m;i++)
{
int x,y;
long long a,b;
scanf("%d%d%lld%lld",&x,&y,&a,&b);
if(i!=0)
printf(" ");
printf("%lld",solve(x,y,a,b));
}
printf("\n");
}
return 0;
}
wa的可太惨了,睡觉