题目:传送门


这道题根本不用lca,也没有部分分。。。

考虑求两个点xy的lca的深度。

我们将x到树根所有点的值都加1,然后查询y到根的和,其实就是lca的深度。

所以本题离线一下上树剖乱搞就可以了。


AC代码如下:
718ms 17348Kib

 #include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm> using namespace std; namespace StandardIO { template<typename T> inline void read (T &x) {
x=;T f=;char c=getchar();
for (; c<''||c>''; c=getchar()) if (c=='-') f=-;
for (; c>=''&&c<=''; c=getchar()) x=x*+c-'';
x*=f;
}
template<typename T> inline void write (T x) {
if (x<) putchar('-'),x=-x;
if (x>=) write(x/);
putchar(x%+'');
} } using namespace StandardIO; namespace Solve { const int MOD=;
const int N=; struct Tree {
int tree[N*],tag[N*];
void pushdown (int pos,int left,int right) {
if (tag[pos]) {
int mid=(left+right)/;
tree[pos*]+=(mid-left+)*tag[pos],tree[pos*]%=MOD;
tree[pos*+]+=(right-mid)*tag[pos],tree[pos*+]%=MOD;
tag[pos*]+=tag[pos],tag[pos*+]+=tag[pos],tag[pos*]%=MOD,tag[pos*+]%=MOD;
tag[pos]=;
}
}
void pushup (int pos) {
tree[pos]=tree[pos*]+tree[pos*+],tree[pos]%=MOD;
}
void update (int pos,int left,int right,int L,int R,int add) {
if (L<=left&&right<=R) {
tree[pos]+=add*(right-left+),tree[pos]%=MOD;
tag[pos]+=add,tag[pos]%=MOD;
return;
}
pushdown(pos,left,right);
int mid=(left+right)/;
if (L<=mid) update(pos*,left,mid,L,R,add);
if (R>mid) update(pos*+,mid+,right,L,R,add);
pushup(pos);
}
int query (int pos,int left,int right,int L,int R) {
if (L<=left&&right<=R) return tree[pos];
pushdown(pos,left,right);
int mid=(left+right)/;
int ans=;
if (L<=mid) ans+=query(pos*,left,mid,L,R),ans%=MOD;
if (R>mid) ans+=query(pos*+,mid+,right,L,R),ans%=MOD;
return ans;
}
} ljz;
int n,q;
vector<int>M[N];
int dep[N],siz[N],fa[N],son[N];
int ind[N],cnt;
int top[N]; void dfs1 (int now,int father) {
dep[now]=dep[father]+,fa[now]=father,siz[now]=;
for (register vector<int>::iterator i=M[now].begin(); i!=M[now].end(); i++) {
if(*i==father) continue;
dfs1(*i,now);
siz[now]+=siz[*i];
if (siz[*i]>siz[son[now]]) son[now]=*i;
}
}
void dfs2(int now,int tp){
top[now]=tp,ind[now]=++cnt;
if (son[now]) dfs2(son[now],tp);
for (register vector<int>::iterator i=M[now].begin(); i!=M[now].end(); i++) {
if (*i==fa[now]||*i==son[now]) continue;
dfs2(*i,*i);
}
}
void upd (int x,int add){
while (x) {
ljz.update(,,n,ind[top[x]],ind[x],add);
x=fa[top[x]];
}
}
int que (int x) {
int ans=;
while (x) {
ans+=ljz.query(,,n,ind[top[x]],ind[x]),ans%=MOD;
x=fa[top[x]];
}
return ans;
}
int A[N];
struct Q{
int val,ind;
Q () {val=ind=;}
Q (int a,int b) :val(a),ind(b) {}
friend bool operator < (Q a,Q b) {
return a.val<b.val;
}
} s1[N],s2[N];
int a1=,a2=;
int Ans[N]; inline void solve () {
read(n),read(q);
for (register int i=; i<=n; i++) {
int a;
read(a);
M[a+].push_back(i);
}
dfs1(,);
dfs2(,);
for (register int i=; i<=q; i++) {
int a,b,c;
read(a),read(b),read(c);
a++,b++,c++;
A[i]=c;
s1[i]=Q(a-,i),s2[i]=Q(b,i);
}
sort(s1+,s1+q+);
sort(s2+,s2+q+);
while (s1[a1].val==) a1++;
for (register int i=; i<=n; i++) {
upd(i,);
while (s1[a1].val==i) {
Ans[s1[a1].ind]-=que(A[s1[a1].ind])-MOD,Ans[s1[a1].ind]%=MOD;
a1++;
}
while (s2[a2].val==i) {
Ans[s2[a2].ind]+=que(A[s2[a2].ind]),Ans[s2[a2].ind]%=MOD;
a2++;
}
}
for (register int i=; i<=q; i++) {
write(Ans[i]),putchar('\n');
}
} } using namespace Solve; int main () {
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
solve();
}

最新文章

  1. 支付宝PC即时到账和手机网站支付同步
  2. MD5使用
  3. 可在广域网部署运行的QQ高仿版 -- GG叽叽V1.8(源码)
  4. php 碎片笔记
  5. 20145215实验三 敏捷开发与XP实践
  6. Hark的数据结构与算法练习之计数排序
  7. codeforces 323A. Black-and-White Cube 构造
  8. 一个tomcat上放多个webapp问题,那这多个webapp会不会竞争端口呢?不会!安全两码事
  9. 实现windows和linux互传文件
  10. Android --- 字符串\n的换行问题
  11. GitHub基本操作(转)
  12. 前端资讯周报 3.13 - 3.19: WebVR来了!以及如何优化scroll事件性能
  13. ASP.NET Core 运行原理剖析
  14. JAVA线程sleep和wait方法区别
  15. 【uva 1411 Ants蚂蚁们】
  16. 【项目】Selenium和pymongo复习
  17. VLC框架分析
  18. java 多线程 27 :多线程组件之CountDownLatch
  19. 常用的windows注册表大全
  20. JavaScript总结(一)

热门文章

  1. POJ 3370 Halloween treats( 鸽巢原理简单题 )
  2. BZOJ 4990 [USACO17FEB] Why Did the Cow Cross the Road II P (树状数组优化DP)
  3. [luogu2592 ZJOI2008] 生日聚会 (计数dp)
  4. GRUB 引导流程
  5. ARM - Linux嵌入式C/C++各种资料分享【更新日期:2012/04/24】
  6. python_for循环
  7. [LeetCode] 242. 有效的字母异位词 valid-anagram(排序)
  8. IE9以下版本兼容h5标签
  9. 获取ip,判断用户所在城市
  10. volley源代码解析(六)--HurlStack与HttpClientStack之争