树分块

  orz HZWER

  http://hzwer.com/5259.html

  不知为何我原本写的倍增求LCA给WA了……学习了HZWER的倍增新姿势~

  树上分块的转移看vfk博客的讲解吧……(其实是先指向hzwer博客,再跳转vfk和KuribohG……)

  vfk讲的很详细,重点就在于转移的时候无视lca,只有在计算答案的时候临时加进来lca,算完答案再把lca去掉。

 /**************************************************************
Problem: 3757
User: Tunix
Language: C++
Result: Accepted
Time:17180 ms
Memory:17716 kb
****************************************************************/ //BZOJ 3757
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
using namespace std;
void read(int &v){
v=; int sign=; char ch=getchar();
while(ch<''||ch>''){ if (ch=='-') sign=-; ch=getchar();}
while(ch>=''&&ch<=''){ v=v*+ch-''; ch=getchar();}
v*=sign;
}
#define debug
/******************tamplate*********************/
const int N=;
int head[N],to[N],next[N],cnt;
void add(int x,int y){
to[++cnt]=y; next[cnt]=head[x]; head[x]=cnt;
to[++cnt]=x; next[cnt]=head[y]; head[y]=cnt;
}
/*******************edge************************/
int n,m,color[N],root;
int B,belong[N],st[N],top,tot,deep[N];
int fa[N][],bin[];
void dfs(int x){
int bottom=top;
for(int i=;i<=;i++)
if(deep[x]>=bin[i])
fa[x][i]=fa[fa[x][i-]][i-];
else break;
for(int i=head[x];i;i=next[i])
if (to[i]!=fa[x][]){
fa[to[i]][]=x;
deep[to[i]]=deep[x]+;
dfs(to[i]);
if (top-bottom>=B){
++tot;
while(top!=bottom)
belong[st[top--]]=tot;
}
}
st[++top]=x;
}
int LCA(int x,int y){
if (deep[x]<deep[y]) swap(x,y);
int t=deep[x]-deep[y];
for(int i=;bin[i]<=t;i++)
if (t&bin[i]) x=fa[x][i];
D(i,,)
if(fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
if(x==y) return x;
return fa[x][];
}
/*******************dfs&&LCA********************/
struct ques{
int x,y,a,b,num;
bool operator < (const ques &now)const{
if (belong[x]==belong[now.x]) return belong[y]<belong[now.y];
else return belong[x]<belong[now.x];
}
}Q[N]; int num[N],ans=,ANS[N];
bool used[N];
inline void work(int x){
if(!used[x]){
num[color[x]]++;used[x]=;
if(num[color[x]]==) ans++;
}
else{
num[color[x]]--;used[x]=;
if(num[color[x]]==) ans--;
}
} void Xor(int x,int y){
int lca=LCA(x,y);
while(x!=lca) {work(x); x=fa[x][];}
while(y!=lca) {work(y); y=fa[y][];}
} int main(){
bin[]=; F(i,,) bin[i]=bin[i-]<<; read(n); read(m);
B=sqrt(n);
F(i,,n) read(color[i]);
int x,y;
F(i,,n){
read(x); read(y);
if (x==) root=y;
if (y==) root=x;
add(x,y);
}
dfs(root);
tot++;
while(top)belong[st[top--]]=tot; int a,b;
F(i,,m){
read(x); read(y); read(a); read(b);
Q[i]=(ques){x,y,a,b,i};
}
sort(Q+,Q+m+);
//转移的时候不考虑LCA,查答案的时候临时算进来,计算完答案后再把LCA删掉
int lca=(LCA(Q[].x,Q[].y));
Xor(Q[].x,Q[].y);
work(lca);
ANS[Q[].num]=ans;
if (num[Q[].a]!= && num[Q[].b]!= && Q[].a!=Q[].b) ANS[Q[].num]--;
work(lca);
F(i,,m){
Xor(Q[i-].x,Q[i].x);
Xor(Q[i-].y,Q[i].y);
lca=LCA(Q[i].x,Q[i].y);
work(lca);
ANS[Q[i].num]=ans;
if(num[Q[i].a]!= && num[Q[i].b]!= && Q[i].a!=Q[i].b) ANS[Q[i].num]--;
work(lca);
}
F(i,,m) printf("%d\n",ANS[i]);
return ;
}

3757: 苹果树

Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 632  Solved: 223
[Submit][Status][Discuss]

Description

神犇家门口种了一棵苹果树。苹果树作为一棵树,当然是呈树状结构,每根树枝连接两个苹果,每个苹果都可以沿着一条由树枝构成的路径连到树根,而且这样的路径只存在一条。由于这棵苹果树是神犇种的,所以苹果都发生了变异,变成了各种各样的颜色。我们用一个到n之间的正整数来表示一种颜色。树上一共有n个苹果。每个苹果都被编了号码,号码为一个1到n之间的正整数。我们用0代表树根。只会有一个苹果直接根。

有许许多多的人来神犇家里膜拜神犇。可神犇可不是随便就能膜拜的。前来膜拜神犇的人需要正确回答一个问题,才能进屋膜拜神犇。这个问题就是,从树上编号为u的苹果出发,由树枝走到编号为v的苹果,路径上经过的苹果一共有多少种不同的颜色(包括苹果u和苹果v的颜色)?不过神犇注意到,有些来膜拜的人患有色盲症。具体地说,一个人可能会认为颜色a就是颜色b,那么他们在数苹果的颜色时,如果既出现了颜色a的苹果,又出现了颜色b的苹果,这个人只会算入颜色b,而不会把颜色a算进来。

神犇是一个好人,他不会强人所难,也就会接受由于色盲症导致的答案错误(当然答案在色盲环境下也必须是正确的)。不过这样神犇也就要更改他原先数颜色的程序了。虽然这对于神犇来说是小菜一碟,但是他想考验一下你。你能替神犇完成这项任务吗?

Input

输入第一行为两个整数n和m,分别代表树上苹果的个数和前来膜拜的人数。
接下来的一行包含n个数,第i个数代表编号为i的苹果的颜色Coli。
接下来有n行,每行包含两个数x和y,代表有一根树枝连接了苹果x和y(或者根和一个苹果)。
接下来有m行,每行包含四个整数u、v、a和b,代表这个人要数苹果u到苹果v的颜色种数,同时这个人认为颜色a就是颜色b。如果a=b=0,则代表这个人没有患色盲症。

Output

输出一共m行,每行仅包含一个整数,代表这个人应该数出的颜色种数。

Sample Input

5 3
1 1 3 3 2
0 1
1 2
1 3
2 4
3 5
1 4 0 0
1 4 1 3
1 4 1 2

Sample Output

2
1
2

HINT

0<=x,y,a,b<=N
N<=50000
1<=U,V,Coli<=N

Source

[Submit][Status][Discuss]

【BZOJ】【3757】苹果树的更多相关文章

  1. BZOJ 3757: 苹果树

    3757: 苹果树 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1726  Solved: 550[Submit][Status][Discuss] ...

  2. bzoj 3757 苹果树(树上莫队算法)

    [题意] 有若干个询问,询问路径u,v上的颜色总数,另外有要求a,b,意为将a颜色看作b颜色. [思路] vfk真是神系列233. Quote: 用S(v, u)代表 v到u的路径上的结点的集合. 用 ...

  3. BZOJ.3757.苹果树(树上莫队)

    题面链接 /* 代码正确性不保证..(不过交了SPOJ没WA T了最后一个点) 在DFS序做莫队 当一个点不是另一个点的LCA时,需要加上它们LCA的贡献 */ #include <cmath& ...

  4. BZOJ 3757 苹果树 ——莫队算法

    挺好的一道题目,怎么就没有版权了呢?大数据拍过了,精神AC.... 发现几种颜色这性质比较垃圾,不可加,莫队硬上. %了一发popoqqq大神的博客, 看了一波VFK关于糖果公园的博客, 又找了wjm ...

  5. 【BZOJ】3757: 苹果树

    http://www.lydsy.com/JudgeOnline/problem.php?id=3757 题意:n个节点的树,每个点有一种颜色.现有m种询问,每次询问x y a b表示x到y的路径上颜 ...

  6. bzoj 3757 树上莫队

    感谢以下文章作者: http://blog.csdn.net/kuribohg/article/details/41458639 http://vfleaking.blog.163.com/blog/ ...

  7. BZOJ - 3757 树上莫队解决离线路径问题 & 学习心得

    题意:给你一棵树,求u,v最短路径的XXX(本题是统计权值种类) 今天课上摸鱼学了一种有意思的处理路径方式(其实是链式块状树翻车了看别的),据说实际运行跑的比XX记者还快 大概就是像序列莫队那样 首先 ...

  8. 【BZOJ】3052: [wc2013]糖果公园

    http://www.lydsy.com/JudgeOnline/problem.php?id=3052 题意:n个带颜色的点(m种),q次询问,每次询问x到y的路径上sum{w[次数]*v[颜色]} ...

  9. 【BZOJ-3757】苹果树 块状树 + 树上莫队

    3757: 苹果树 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1305  Solved: 503[Submit][Status][Discuss] ...

随机推荐

  1. STP详解

    STP详解 Write From YangWj Wednesday, March 5, 2014 一. 生成树协议 STP的主要任务是阻止在第2层网络(网桥或交换机)产生网络环路,它警惕的监视着网络中 ...

  2. js 动态添加元素(div、li、img等)及设置属性

    把一串 html 标签赋给一个 javascript 变量,除属性的值要用转义的双引号外,某些时候字符串还很长,显得有些复杂.如果用 js 动态添加元素,就不会有那么复杂的字符串出现,代码阅读性强一点 ...

  3. 获取字符串对应的MD5值 (AL16UTF16LE)

    CREATE OR REPLACE FUNCTION fn_md5_utf16le (InputString IN VARCHAR2) RETURN VARCHAR2 IS retval ); /** ...

  4. ionic2 Navigation实现报错:No component factory found for "MyComponent"

    ionic2 写的代码里面,跳转的时候报了一个 No component factory found for "RechargeSucceed" recharge() { let ...

  5. Aborting a running program

    In the event that a calculation appears to be running excessively long, one can abort thecalculation ...

  6. 3月7日 Maximum Subarray

    间隔2天,继续开始写LeetCodeOj. 原题: Maximum Subarray 其实这题很早就看了,也知道怎么做,在<编程珠玑>中有提到,求最大连续子序列,其实只需要O(n)的复杂度 ...

  7. 状态模式(State)

    状态模式,从字面意思上来讲应该是很简单的,就是针对实际业务上的内容,当类的内部的状态发生改变时,给出不同的响应体,就像现实中的人一样,早上没有吃饭,状态不好,上班.上课都会打哈欠,中午了,吃过午饭,又 ...

  8. 【风马一族_xml】xml的基本讲解笔记

    xml是如何保存数据的 在xml语言中,它允许用户自定义标签.每个标签用于描述一段数据; 一个标签可以分为开始标签和结束标签,在开始标签和结束标签之间又可以嵌套其它标签,利用标签间的嵌套其它标签,利用 ...

  9. 使用公司自己的maven服务器时,本地 maven 的配置方法

    使用公司的maven服务器,可以加速jar包的下载. 如果要使用公司的maven服务器,需要对本地maven配置文件conf/settings.xml做相应修改,具体改法有两种.   一.mirror ...

  10. LINQ to XML(1)

    LINQ to XML可以两种方式和XML配合使用.第一种方式是作为简化的XML操作API,第二种方式是使用LINQ查询工具.下面我使用的是第二种方式. 主要内容:用LINQ查询语句对XML文件里的数 ...