裸的树链剖分。

对于安装 查询和维护到根路径

对于卸载 查询和维护子树信息

一开始线段树add[]标记要全赋值为-1


 #include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std; typedef long long LL; #define N 200010 int id;
int fa[N],siz[N],top[N],son[N];
int pos[N],r[N];
LL sum[N<<],add[N<<]; struct Node
{
int to,next;
}e[N];
int head[N];
int cnt; int a; char s; int n,q; int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
} void link(int x,int y)
{
e[++cnt]=(Node){y,head[x]};
head[x]=cnt;
} void dfs(int x)
{
siz[x]=;
for (int i=head[x],mx=;i;i=e[i].next)
if (e[i].to!=fa[x])
{
fa[e[i].to]=x;
dfs(e[i].to);
siz[x]+=siz[e[i].to];
if (siz[e[i].to]>mx)
mx=siz[e[i].to],son[x]=e[i].to;
}
} void dfs2(int x,int cha)
{
top[x]=cha;
pos[x]=++id;
if (son[x])
dfs2(son[x],cha);
for (int i=head[x];i;i=e[i].next)
if(e[i].to!=fa[x] && e[i].to!=son[x])
dfs2(e[i].to,e[i].to);
r[x]=id;
} void pushup(int now)
{
sum[now]=sum[now<<]+sum[now<<|];
} void pushdown(int nowl,int nowr,int now,int mid)
{
if (add[now]!=-)
{
LL t=add[now];
add[now]=-;
add[now<<]=t;
add[now<<|]=t;
sum[now<<]=t*(mid-nowl+);
sum[now<<|]=t*(nowr-mid);
}
} void update(int nowl,int nowr,int now,int s,int t,LL d)
{
if (nowl>=s && nowr<=t)
{
add[now]=d;
sum[now]=(nowr-nowl+)*d;
return ;
}
int mid=(nowl+nowr)>>;
pushdown(nowl,nowr,now,mid);
if (s<=mid)
update(nowl,mid,now<<,s,t,d);
if (t>mid)
update(mid+,nowr,now<<|,s,t,d);
pushup(now);
} int query(int nowl,int nowr,int now,int s,int t)
{
if (nowl>=s && nowr<=t)
return sum[now];
int mid=(nowl+nowr)>>;
int ans=;
pushdown(nowl,nowr,now,mid);
if (s<=mid)
ans+=query(nowl,mid,now<<,s,t);
if (t>mid)
ans+=query(mid+,nowr,now<<|,s,t);
return ans;
} int work1(int x)
{
int ans,res=;
while (x)
{
ans=query(,n,,pos[top[x]],pos[x]);
res+=pos[x]-pos[top[x]]+-ans;
update(,n,,pos[top[x]],pos[x],);
if (ans)
break;
x=fa[top[x]];
}
return res;
} int work2(int x)
{
int res;
res=query(,n,,pos[x],r[x]);
update(,n,,pos[x],r[x],);
return res;
} int main()
{
n=read();
for (int i=;i<n;i++)
{
a=read();
link(a+,i+);
}
dfs();
dfs2(,);
memset(add,-,sizeof(add));
q=read();
while (q--)
{
scanf("%c",&s);
a=read();
if (s=='i')
printf("%d\n",work1(a+));
else
printf("%d\n",work2(a+));
}
return ;
}

最新文章

  1. Python使用总结二
  2. Java线程间通信方式剖析——Java进阶(四)
  3. TAP/TUN浅析(一)
  4. web桌面程序之图标拖动排序的分析
  5. [转]Dropdownlist doesn&#39;t postback after Page_ClientValidate()
  6. canvas三角函数做椭圆运动效果
  7. C 数组模拟阶乘运算
  8. Java SimpleDateFormat[转]
  9. Java构造和解析Json数据的两种方法详解二
  10. linux信号处理及libcurl的坑
  11. Win2012 R2 IIS8.5+PHP(FastCGI)+MySQL运行环境搭建教程
  12. Candy
  13. hadoop_并行写操作思路_2
  14. C++中引用用于结构
  15. [20170705]diff比较执行结果的内容.txt
  16. 690. Employee Importance
  17. require.js 简洁入门
  18. 阿里druid连接池监控配置
  19. mysql主从复制-方案1
  20. Use a layout_width of 0dip instead of fill_parent for better performance

热门文章

  1. 【MSSQL】MDF、NDF、LDF文件的含义
  2. 阿里云 Django部署参考
  3. iframe天气预报
  4. Android四大核心组件之Activity
  5. stark组件之显示页面内容搭建(六)
  6. 82-Ichimoku Kinko Hyo 一目平衡表.(2015.7.3)
  7. 【05】AJAX实例-检测用户名是否存在(实例)
  8. 7-26 Windows消息队列(25 分)(堆排序)
  9. 数位dp 3943 二分法
  10. .net如何统计在线人数