SP10707 COT2 - Count on a tree II (树上莫队)
大概学了下树上莫队, 其实就是在欧拉序上跑莫队, 特判lca即可.
- #include <iostream>
- #include <algorithm>
- #include <cstdio>
- #include <math.h>
- #include <set>
- #include <map>
- #include <queue>
- #include <string>
- #include <string.h>
- #include <bitset>
- #define REP(i,a,n) for(int i=a;i<=n;++i)
- #define PER(i,a,n) for(int i=n;i>=a;--i)
- #define hr putchar(10)
- #define pb push_back
- #define lc (o<<1)
- #define rc (lc|1)
- #define mid ((l+r)>>1)
- #define ls lc,l,mid
- #define rs rc,mid+1,r
- #define x first
- #define y second
- #define io std::ios::sync_with_stdio(false)
- #define endl '\n'
- #define DB(a) ({REP(i,1,n) cout<<a[i]<<' ';hr;})
- using namespace std;
- typedef long long ll;
- typedef pair<int,int> pii;
- const int P = 1e9+7, INF = 0x3f3f3f3f;
- ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
- ll qpow(ll a,ll n) {ll r=1%P;for (a%=P;n;a=a*a%P,n>>=1)if(n&1)r=r*a%P;return r;}
- ll inv(ll x){return x<=1?1:inv(P%x)*(P-P/x)%P;}
- //head
- const int N = 1e5+10;
- int n, m, a[N], b[N];
- vector<int> g[N];
- int fa[N], son[N], L[N], R[N], no[N];
- int top[N], dep[N], sz[N];
- int sqn, cnt, ans[N], blo[N], ff[N], vis[N];
- struct _ {
- int l,r,lca,id;
- bool operator < (const _ & rhs) const {
- return blo[l]^blo[rhs.l]?l<rhs.l:blo[l]&1?r<rhs.r:r>rhs.r;
- }
- } q[N];
- void dfs(int x, int d, int f) {
- fa[x]=f,sz[x]=1,dep[x]=d,L[x]=++*L,no[*L]=x;
- for (int y:g[x]) if (y!=f) {
- dfs(y,d+1,x), sz[x]+=sz[y];
- if (sz[y]>sz[son[x]]) son[x]=y;
- }
- R[x]=++*L,no[*L]=x;
- }
- void dfs(int x, int tf) {
- top[x]=tf;
- if (son[x]) dfs(son[x],tf);
- for (int y:g[x]) if (!top[y]) dfs(y,y);
- }
- int lca(int x, int y) {
- while (top[x]!=top[y]) {
- if (dep[top[x]]<dep[top[y]]) swap(x,y);
- x = fa[top[x]];
- }
- return dep[x]<dep[y]?x:y;
- }
- void add(int x) {
- if (vis[x]) {if (--ff[a[x]]==0) --cnt;}
- else {if (++ff[a[x]]==1) ++cnt;}
- vis[x] ^= 1;
- }
- int main() {
- scanf("%d%d", &n, &m), sqn=sqrt(n);
- REP(i,1,n) scanf("%d",a+i),b[i]=a[i];
- sort(b+1,b+1+n),*b=unique(b+1,b+1+n)-b-1;
- REP(i,1,n) a[i]=lower_bound(b+1,b+1+*b,a[i])-b;
- REP(i,1,2*n) blo[i]=i/sqn;
- REP(i,2,n) {
- int u, v;
- scanf("%d%d", &u, &v);
- g[u].pb(v),g[v].pb(u);
- }
- dfs(1,1,0),dfs(1,1);
- REP(i,1,m) {
- int x, y;
- scanf("%d%d", &x, &y);
- if (L[x]>L[y]) swap(x,y);
- int _lca = lca(x,y);
- if (_lca==x) q[i].l=L[x];
- else q[i].l=R[x],q[i].lca=_lca;
- q[i].id=i, q[i].r=L[y];
- }
- sort(q+1,q+1+m);
- int ql=1,qr=0;
- REP(i,1,m) {
- while (ql<q[i].l) add(no[ql++]);
- while (qr>q[i].r) add(no[qr--]);
- while (ql>q[i].l) add(no[--ql]);
- while (qr<q[i].r) add(no[++qr]);
- if (q[i].lca) add(q[i].lca);
- ans[q[i].id] = cnt;
- if (q[i].lca) add(q[i].lca);
- }
- REP(i,1,m) printf("%d\n", ans[i]);
- }
SP10707 COT2 - Count on a tree II (树上莫队)的更多相关文章
- SP10707 COT2 - Count on a tree II [树上莫队学习笔记]
树上莫队就是把莫队搬到树上-利用欧拉序乱搞.. 子树自然是普通莫队轻松解决了 链上的话 只能用树上莫队了吧.. 考虑多种情况 [X=LCA(X,Y)] [Y=LCA(X,Y)] else void d ...
- spoj COT2 - Count on a tree II 树上莫队
题目链接 http://codeforces.com/blog/entry/43230树上莫队从这里学的, 受益匪浅.. #include <iostream> #include < ...
- SPOJ COT2 Count on a tree II 树上莫队算法
题意: 给出一棵\(n(n \leq 4 \times 10^4)\)个节点的树,每个节点上有个权值,和\(m(m \leq 10^5)\)个询问. 每次询问路径\(u \to v\)上有多少个权值不 ...
- [SPOJ]Count on a tree II(树上莫队)
树上莫队模板题. 使用欧拉序将树上路径转化为普通区间. 之后莫队维护即可.不要忘记特判LCA #include<iostream> #include<cstdio> #incl ...
- SP10707 COT2 - Count on a tree II 莫队
链接 https://vjudge.net/problem/SPOJ-COT2 https://www.luogu.org/problemnew/show/SP10707 思路 dfs欧拉序转化为普通 ...
- [SP10707]COT2 - Count on a tree II
题目大意:有一棵$n$个节点的树,第$i$个点有一个颜色$C_i$,$m$组询问,每次问$x->y$的路径上有多少种颜色 题解:树上莫队,把树按欧拉序展开成一条链,令第$i$个节点第一次出现在序 ...
- SP10707 COT2 - Count on a tree II 莫队上树
题意:求一条链 \((u,v)\) 上不同的颜色数. 我们可以求出树的出栈入栈序(or 括号序?我也不确定). 图(from attack) 然后有一个很优美的性质: 设点 \(u\) 的入栈时间为 ...
- SPOJ COT2 - Count on a tree II(LCA+离散化+树上莫队)
COT2 - Count on a tree II #tree You are given a tree with N nodes. The tree nodes are numbered from ...
- COT2 - Count on a tree II(树上莫队)
COT2 - Count on a tree II You are given a tree with N nodes. The tree nodes are numbered from 1 to N ...
随机推荐
- Vue内置的Component标签用于动态切换组件
html <div id="app"> <component :is="cut"></component> <butt ...
- Unity3D学习笔记(三十三):矩阵
矩阵 矩阵就是一行和列组织起来的矩形数字块. 矩阵可以理解为是向量的数组. 矩阵的维度和记法 矩阵的维度是包含多少行多少列!例如1行2列的矩阵 记法:矩阵m中,对于第1行第2列的元素,我们记为m1 ...
- Hadoop技术内幕1——源代码环境准备
Hadoop核心 1.HDFS:高容错性.高伸缩性……,允许用户将Hadoop部署在廉价的硬件上,构建分布式系统 2.MapReduce:分布式计算框架,允许用户在不了解分布式系统底层细节的情况下,开 ...
- Latex 算法过长 分页显示方法
参考: Algorithm tag and page break Latex 算法过长 分页显示方法 1.引用algorithm包: 2.在\begin{document}前加上以下Latex代码: ...
- 1、iptables-netfilter基础
.iptables: 包过滤型防火墙功能.四表五链 .iptables规则.规则管理工具.iptables命令 .iptables链管理.规则管理.查看等 .iptables匹配条件.目标.显式扩展. ...
- 手把手教你学习R语言
本文为带大家了解R语言以及分段式的步骤教程! 人们学习R语言时普遍存在缺乏系统学习方法的问题.学习者不知道从哪开始,如何进行,选择什么学习资源.虽然网络上有许多不错的免费学习资源,然而它们多过了头,反 ...
- 【Selenium2】【环境搭建】
Windows7 64位 Mozilla Firefox 36.0.4 + Firebug 2.0.19 + FirePath 0.9.7.1.1-signed.1-signed 火狐历史版本:ht ...
- Educational Codeforces Round 25 E. Minimal Labels 拓扑排序+逆向建图
E. Minimal Labels time limit per test 1 second memory limit per test 256 megabytes input standard in ...
- Easyui使用心得(1)--DateGrid表格
最近一直在用easyui这个控件,有一点心得,在这里和大家分享一下,也是对自己工作的一个小小的总结,希望可以形成一个完整的Easyui的笔记体系,可以方便更多的人 因为自己也是在摸索中前进,难免有遗漏 ...
- scikit_learn逻辑回归类库
来自:刘建平 1.概述 在scikit-learn中,与逻辑回归有关的主要有3个类.LogisticRegression, LogisticRegressionCV 和 logistic_regres ...