2操作可以转化成x的权值在i时刻变成了1,然后查询的操作相当于查询i - c[i] 时刻 x->y链上权值和

可以差分成 \[f(x) + f(y) - f(\text{lca}) - f(fa[lca])\]

f是指根到一个点链上的权值和

这个可以直接写成

x子树中跟链无关的点会抵消掉(x子树中的所有点dfs序的左端点和右端点都被x的dfs序包含 +1的位置和-1的位置都被覆盖了,所以会抵消)

(那个add(l[x[i]] + siz[x[i]], -1)后来被我改成remove了

第一个查询就是查询链长而已。。

复杂度\[O(mlogn)\]

#include <bits/stdc++.h>
using namespace std;typedef double lf;
typedef long long ll;
typedef long double llf;
typedef pair<ll, ll> pll;
typedef unsigned int uint;
typedef pair<int, int> pii;
typedef unsigned long long ull;bool Debug;
const int mod = 1e9 + 7, MAXN = 2e5 + 7, inft = 1e9;
const ll infl = 1ll << 60;#define xx first
#define yy second
#define pb push_back
#define mp make_pair
#define mset(a, b) memset(a, b, sizeof(a))
#define debug(...) if (Debug) fprintf(stderr, __VA_ARGS__)
#define lop(i,a,b) for(int i = (a), i##end = (b); i <= i##end; ++i)
#define dlop(i,a,b) for(int i = (a), i##end = (b); i >= i##end; --i)
#define ergo(a) for(__typeof(a.end())it = (a).begin(), it##end = (a).end(); it != it##end; ++it)template<class A, class B> inline void chmax(A &x, B y) {if (x < y) x = y;}
template<class A, class B> inline void chmin(A &x, B y) {if (x > y) x = y;}
template<class A, class B> inline A max(A a, B b) {return a > b ? a : b;}
template<class A, class B> inline A min(A a, B b) {return a < b ? a : b;}
template<class A, class B> inline A gcd(A a, B b) {if (a < b) swap(a, b); if (!b) return a; while (A t = a % b) a = b, b = t; return b;}
template<class A, class B> inline A lcm(A a, B b) {return a / gcd(a, b) * b;}
template<class A, class B> inline A Pow(A a, B b) {A ret; for (ret = 1; b; b >>= 1) {if (b & 1) ret = ret * 1ll * a % mod; a = a * 1ll * a % mod;} return ret % mod;}
template<class T> inline T abs(T x) {return x >= 0 ? x : -x;}
template<class T> inline T sqr(T x) {return x * x;}struct IO {struct Cg {inline int operator()() {return getchar();}};struct Cp {inline void operator()(int x) {putchar(x);}};
#define IS(x) (x == 10 || x == 13 || x == ' ')
#define OP operator
#define RT return *this
#define RX x=0;int t=P();while((t<'0'||t>'9')&&t!='-')t=P();f=1;\
if(t=='-')t=P(),f=-1;x=t-'0';for(t=P();t>='0'&&t<='9';t=P())x=x*10+t-'0'
#define RL if(t=='.'){lf u=0.1;for(t=P();t>='0'&&t<='9';t=P(),u*=0.1)x+=u*(t-'0');}if(f==-1)x=-x;
#define RU x=0;int t=P();while(t<'0'||t>'9')t=P();x=t-'0';for(t=P();t>='0'&&t<='9';t=P())x=x*10+t-'0'
#define TR *this,x;return xtemplate<typename T>struct Fr {int f; T P; inline Fr&OP, (int&x) {RX; x *= f; RT;} inline OP int() {int x; TR;} inline Fr&OP, (ll &x) {RX; x *= f; RT;} inline OP ll() {ll x; TR;} inline Fr&OP, (char&x) {for (x = P(); IS(x); x = P()); RT;} inline OP char() {char x; TR;} inline Fr&OP, (char*x) {char t = P(); for (; IS(t); t = P()); if (~t) {for (; !IS(t) && ~t; t = P()) * x++ = t;}*x++ = 0; RT;} inline Fr&OP, (lf&x) {RX; RL; RT;} inline OP lf() {lf x; TR;} inline Fr&OP, (llf&x) {RX; RL; RT;} inline OP llf() {llf x; TR;} inline Fr&OP, (uint&x) {RU; RT;} inline OP uint() {uint x; TR;} inline Fr&OP, (ull&x) {RU; RT;} inline OP ull() {ull x; TR;}};Fr<Cg>in;
#define WI if(x){if(x<0)P('-'),x=-x;c=0;while(x)s[c++]=x%10+'0',x/=10;while(c--)P(s[c]);}else P('0')
#define WL if(y){lf t=0.5;for(int i=y;i--;)t*=0.1;if(x>=0)x+=t;else x-=t,P('-');*this,(ll)(abs(x));P('.');if(x<0)\
x=-x;while(y--){x*=10;x-=floor(x*0.1)*10;P(((int)x)%10+'0');}}else if(x>=0)*this,(ll)(x+0.5);else *this,(ll)(x-0.5);
#define WU if(x){c=0;while(x)s[c++]=x%10+'0',x/=10;while(c--)P(s[c]);}else P('0')template<typename T>struct Fw {int c, s[24]; T P; inline Fw&OP, (int x) {WI; RT;} inline Fw&OP()(int x) {WI; RT;} inline Fw&OP, (uint x) {WU; RT;} inline Fw&OP()(uint x) {WU; RT;} inline Fw&OP, (ll x) {WI; RT;} inline Fw&OP()(ll x) {WI; RT;} inline Fw&OP, (ull x) {WU; RT;} inline Fw&OP()(ull x) {WU; RT;} inline Fw&OP, (char x) {P(x); RT;} inline Fw&OP()(char x) {P(x); RT;} inline Fw&OP, (const char*x) {while (*x)P(*x++); RT;} inline Fw&OP()(const char*x) {while (*x)P(*x++); RT;} inline Fw&OP()(lf x, int y) {WL; RT;} inline Fw&OP()(llf x, int y) {WL; RT;}};Fw<Cp>out;
} io;
#define in io.in
#define out io.outstruct Edge {int v, next;
} G[MAXN]; int head[MAXN], son[MAXN], dep[MAXN], anc[MAXN], tot, l[MAXN], idx, ans1[MAXN], ans2[MAXN], s, n, m, x[MAXN], y[MAXN], c[MAXN], op, p, siz[MAXN], top[MAXN], k; inline void add(int u, int v) {G[++tot] = (Edge) {v, head[u]}; head[u] = tot;
}#define cur G[i].v
void dfs1(int u) {dep[u] = dep[anc[u]] + 1, siz[u] = 1;for (int i = head[u]; i; i = G[i].next) {    dfs1(cur);siz[u] += siz[cur];if (siz[cur] >= siz[son[u]]) son[u] = cur;}
}
void dfs2(int u, int t) {top[u] = t; l[u] = ++idx;if (son[u]) dfs2(son[u], t);for(int i = head[u]; i; i = G[i].next) if (cur != son[u]) dfs2(cur, cur);
}
#undef cur
inline int LCA(int u, int v) {while(top[u] != top[v]) dep[top[u]] >= dep[top[v]] ? u = anc[top[u]] : v = anc[top[v]];return dep[u] < dep[v] ? u : v;
}
vector<int>q[MAXN];
struct BIT {int t[MAXN];inline void add(register int k) {while (k <= n) ++t[k], k += k & (-k);}inline void remove(register int k) {while (k <= n) --t[k], k += k & (-k);}inline int Sum(int k) {register int ret = 0;while (k) ret += t[k], k -= k & (-k);return ret;}
} bit;int main() {in, n;lop(i, 1, n) {in, anc[i];if (!anc[i]) s = i;else add(anc[i], i);}dfs1(s), dfs2(s, s);in, m;lop(i, 1, m) {in, k, x[i];if (k == 1) {in, y[i], c[i];c[i] = i - c[i];q[max(1, c[i])].pb(i);// c[i] <= 0 is equal to c[i] = 1 }}lop(i,1,m) {for(vector<int>::iterator it = q[i].begin(); it != q[i].end(); ++it) {int lca = LCA(x[*it], y[*it]), fa = anc[lca];ans1[*it] = dep[x[*it]] + dep[y[*it]] - dep[fa] - dep[lca];ans2[*it] = bit.Sum(l[x[*it]]) + bit.Sum(l[y[*it]]) - bit.Sum(l[fa]) - bit.Sum(l[lca]);}if (!y[i]) bit.add(l[x[i]]), bit.remove(l[x[i]] + siz[x[i]]);// the node M between l[x[i]] and l[x[i]] + siz[x[i]](M in x[i]'s subtree) will not influence the result because +1 and -1 = 0}lop(i,1,m) if (ans1[i]) out, ans1[i], ' ', ans2[i], '\n';return 0;
}

转载于:https://www.cnblogs.com/storz/p/10191094.html

[BZOJ4448][SCOI2015]情报传递[dfs序+树状数组]相关推荐

  1. 【dfs序+树状数组】多次更新+求结点子树和操作,牛客小白月赛24 I题 求和

    前置知识点 dfs遍历 树状数组/线段树知识 链接 I题 求和. 题意 已知有 n 个节点,有 n−1 条边,形成一个树的结构. 给定一个根节点 k,每个节点都有一个权值,节点i的权值为 vi 给 m ...

  2. 计蒜客(青出于蓝胜于蓝) dfs序+树状数组

    武当派一共有 n 人,门派内 n 人按照武功高低进行排名,武功最高的人排名第 1,次高的人排名第 2,... 武功最低的人排名 第 n.现在我们用武功的排名来给每个人标号,除了祖师爷,每个人都有一个师 ...

  3. HDU - 5788 Level Up(主席树+dfs序+树状数组)

    题目链接:点击查看 题目大意:给出一棵有向树,每个节点都有一个初始的权值 a[ i ] ,和一个通过计算得到的权值 mid[ i ] ,mid 数组的计算方法如下:mid[ u ] 为结点 u 及其子 ...

  4. 【BZOJ2434】[NOI2011]阿狸的打字机 AC自动机+DFS序+树状数组

    [BZOJ2434][NOI2011]阿狸的打字机 Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P ...

  5. 【bzoj2434】[Noi2011]阿狸的打字机 AC自动机+Dfs序+树状数组

    题目描述 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小 ...

  6. CF-547E(Mike and Friends)后缀数组+线段树 AC自动机+DFS序+树状数组

    题目链接 题意 NNN个串,每次询问区间[L,R][L,R][L,R]中有多少子串SiS_iSi​ 思路 把NNN个串合成一个长字符串,对这个长字符串求后缀数组,包含SiS_iSi​的子串的heigh ...

  7. HDU - 5877 Weak Pair (dfs序+树状数组+离散化)

    VJ地址 题意:给一个有根树给你,计算一下满足下列条件的序列对的数目 (1)u是v的祖先(不能是它自己) (2)a[v]*a[u]<=k 思路:用DFS序分裂每一条链,使链上的点都是当前加入点的 ...

  8. 2018蓝桥杯模拟赛·青出于蓝而胜于蓝 DFS序+树状数组

    武当派一共有 nnn 人,门派内 nnn 人按照武功高低进行排名,武功最高的人排名第 111,次高的人排名第 222,... 武功最低的人排名第 nnn.现在我们用武功的排名来给每个人标号,除了祖师爷 ...

  9. 【POJ - 3321】 Apple Tree(dfs序 + 线段树维护 或 dfs序 + 树状数组维护)

    题干: There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the t ...

最新文章

  1. apache 重定向tomcat端口_Tomcat
  2. python元组(tuple)使用示例+常用方法+列表(list)和元组(tuple)的异同?
  3. ubuntu nginx php-fpm mysql_Ubuntu下安装Nginx,PHP5(及PHP-FPM),MySQL
  4. 神经网络与机器学习 笔记—卷积神经网络(CNN)
  5. 埃尔米特插值(等距节点,只用一个点的导数构造n+1阶Hermite多项式)Python实现
  6. MySQL高级 - SQL优化 - 子查询优化
  7. 解决用Python对Sqlite进行数据更新比较慢的一种方法
  8. 卡图星小机器人怎么过_安徽交通广播90.8专题报道:阿尔法大蛋机器人,家里的新成员!...
  9. Netpas:不一样的SD-WAN+ 保障网络通讯品质
  10. Visual Studio 编辑R语言环境搭建
  11. 如何在网上买到下铺票2020_如何在网上购票选择下铺和靠窗的座位
  12. 使用 ReportLab 绘制 PDF
  13. android tabhost的使用方法,android TabHost的基本使用
  14. 格雷码与二进制码之间的相互转换
  15. spark学习9:sparkStreaming
  16. awk及sum求和!
  17. 计算机网络连接限制,网络连接受限,详细教您网络连接受限怎么解决
  18. java七牛云工具类_您应该知道的7个Java工具
  19. 【微信小程序-初级实战】商品/表单编辑
  20. [读书笔记] Deep learning by Yann LeCun1,2, Yoshua Bengio3 Geoffrey Hinton4,5 on nature

热门文章

  1. acwing算法题--多重背包问题二
  2. Golang 判断key是否在map中
  3. leetcode算法题--掷骰子的N种方法
  4. systemctl和service
  5. 计算机技术综合应用,浅谈计算机技术综合应用能力培养.pdf
  6. matlab paticalcoff,关于DOA估计中加权前后向空间平滑算法的仿真问题
  7. CGRect CGFloat 不能使用
  8. 一脸懵逼学习Storm的搭建--(一个开源的分布式实时计算系统)
  9. 关于双机热备,你该知道那些问题?
  10. Java SE(2)