线段树合并的话这个noip最难题就是个裸题了。

  注意merge最后return x,以及如果需要区间查询的话这里还需要up,无数次死于这里。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 300010
int n,m,p[N],a[N],fa[N][],deep[N],ans[N],root[][N],cnt[]={},t=;
vector<int> op1[N],op2[N];
struct data{int to,nxt;
}edge[N<<];
struct data2{int l,r,x;
}tree[][N<<];
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
void dfs(int k)
{
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=fa[k][])
{
fa[edge[i].to][]=k;
deep[edge[i].to]=deep[k]+;
dfs(edge[i].to);
}
}
int lca(int x,int y)
{
if (deep[x]<deep[y]) swap(x,y);
for (int j=;~j;j--) if (deep[fa[x][j]]>=deep[y]) x=fa[x][j];
if (x==y) return x;
for (int j=;~j;j--) if (fa[x][j]!=fa[y][j]) x=fa[x][j],y=fa[y][j];
return fa[x][];
}
int merge(int x,int y,int l,int r,int p)
{
if (!x||!y) return x|y;
if (l==r) {tree[p][x].x+=tree[p][y].x;return x;}
int mid=l+r>>;
tree[p][x].l=merge(tree[p][x].l,tree[p][y].l,l,mid,p);
tree[p][x].r=merge(tree[p][x].r,tree[p][y].r,mid+,r,p);
return x;
}
void ins(int &k,int x,int l,int r,int v,int p)
{
if (!k) k=++cnt[p];
if (l==r) {tree[p][k].x+=v;return;}
int mid=l+r>>;
if (x<=mid) ins(tree[p][k].l,x,l,mid,v,p);
else ins(tree[p][k].r,x,mid+,r,v,p);
}
int query(int k,int l,int r,int x,int p)
{
if (!k) return ;
if (l==r) return tree[p][k].x;
int mid=l+r>>;
if (x<=mid) return query(tree[p][k].l,l,mid,x,p);
else return query(tree[p][k].r,mid+,r,x,p);
}
void getans(int k)
{
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=fa[k][])
{
getans(edge[i].to);
root[][k]=merge(root[][k],root[][edge[i].to],,n<<,);
root[][k]=merge(root[][k],root[][edge[i].to],,n<<,);
}
for (int i=;i<op1[k].size();i++)
if (op1[k][i]>) ins(root[][k],op1[k][i],,n<<,,);
else ins(root[][k],-op1[k][i],,n<<,-,);
for (int i=;i<op2[k].size();i++)
if (op2[k][i]>) ins(root[][k],op2[k][i],,n<<,,);
else ins(root[][k],-op2[k][i],,n<<,-,);
ans[k]+=query(root[][k],,n<<,deep[k]+a[k],)+query(root[][k],,n<<,deep[k]-a[k]+n,);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj4719.in","r",stdin);
freopen("bzoj4719.out","w",stdout);
#endif
n=read(),m=read();
for (int i=;i<n;i++)
{
int x=read(),y=read();
addedge(x,y),addedge(y,x);
}
fa[][]=;dfs();
for (int j=;j<;j++)
for (int i=;i<=n;i++)
fa[i][j]=fa[fa[i][j-]][j-];
for (int i=;i<=n;i++) a[i]=read();
for (int i=;i<=m;i++)
{
int x=read(),y=read(),l=lca(x,y);
if (l!=x) op1[x].push_back(deep[x]),op1[l==?:fa[l][]].push_back(-deep[x]);
if (l!=y) op2[y].push_back(deep[l]*-deep[x]+n),op2[l==x?(l==?:fa[l][]):l].push_back(deep[x]-deep[l]*-n);
if (l==x&&l==y&&a[l]==) ans[l]++;
}
getans();
for (int i=;i<=n;i++) printf("%d ",ans[i]);
return ;
}

最新文章

  1. HTML5- Canvas入门(二)
  2. Android 插件化
  3. spring的定时任务配置
  4. C# Redis实战(二) [转]
  5. SharePoint 2010 RBS 安装和配置遇到的一个问题
  6. flash中函数的理解
  7. eight - zoj 1217 poj 1077
  8. 后缀自动机(SAM)模板
  9. Max Min
  10. HTTP Digest authentication
  11. 转 Oracle 12c 使用scott等普通用户的方法
  12. C#操作EML邮件文件实例(含HTML格式化邮件正文和附件)
  13. django rest framework pagination
  14. Java IO(2)阻塞式输入输出(BIO)
  15. OpenShift-EFK日志管理
  16. iOS UI-常用控件
  17. String类的concat()方法
  18. Battery Historian之App耗电量测试
  19. python序列中添加高斯噪声
  20. 面向对象中的@classonlymethod 与 @classmethod的区别

热门文章

  1. 半个小时教你写一个装(bi)逼(she)之地图搜租房
  2. 【轮子狂魔】打造简易无配置的IoC
  3. Configure,Makefile.am, Makefile.in, Makefile文件
  4. 创建第一个Scrapy项目
  5. 数据库sql优化总结之1-百万级数据库优化方案+案例分析
  6. 初次学习asp.net core的心得
  7. IDEA 创建Spring Boot 项目
  8. Tree - XGBoost with parameter description
  9. AutoCAD 自动管理字体插件[使用ObjectARX C++]
  10. Python如何对折线进行平滑曲线处理?