听说这是动态开点主席树的板子题,但是发现我还不会,于是就来写一写

其实跟主席树一个样子的

这里就是存个板子吧

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define re register
#define max(a,b) ((a)>(b)?(a):(b))
#define maxn 100005
struct E
{
int v,nxt;
}e[maxn<<1];
inline int read()
{
char c=getchar();
int x=0;
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9')
x=(x<<3)+(x<<1)+c-48,c=getchar();
return x;
}
int head[maxn],deep[maxn],top[maxn],son[maxn],sz[maxn],fa[maxn],to[maxn],b[maxn],c[maxn],a[maxn],_[maxn];
int rt[maxn];
int l[maxn*20],r[maxn*20],sum[maxn*20],d[maxn*20];
int cnt,num,tot,n,Q;
void dfs1(int x)
{
sz[x]=1;
int maxx=-1;
for(re int i=head[x];i;i=e[i].nxt)
if(!deep[e[i].v])
{
deep[e[i].v]=deep[x]+1;
fa[e[i].v]=x;
dfs1(e[i].v);
sz[x]+=sz[e[i].v];
if(sz[e[i].v]>maxx) maxx=sz[e[i].v],son[x]=e[i].v;
}
}
void dfs2(int x,int topf)
{
to[x]=++tot;
b[tot]=a[x];
c[tot]=_[x];
top[x]=topf;
if(!son[x]) return;
dfs2(son[x],topf);
for(re int i=head[x];i;i=e[i].nxt)
if(deep[e[i].v]>deep[x]&&son[x]!=e[i].v) dfs2(e[i].v,e[i].v);
}
inline void add_edge(int x,int y)
{
e[++num].v=y;
e[num].nxt=head[x];
head[x]=num;
}
int change(int now,int x,int y,int pos,int val)
{
int root=now;
if(!now) root=++cnt;
if(x==y)
{
d[root]=val,sum[root]=val;
return root;
}
int mid=x+y>>1;
if(pos<=mid) l[root]=change(l[root],x,mid,pos,val);
else r[root]=change(r[root],mid+1,y,pos,val);
d[root]=max(d[l[root]],d[r[root]]);
sum[root]=sum[l[root]]+sum[r[root]];
return root;
}
int query(int now,int x,int y,int ll,int rr)
{
if(!now) return 0;
if(ll<=x&&rr>=y) return sum[now];
int mid=x+y>>1;
if(rr<=mid) return query(l[now],x,mid,ll,rr);
if(ll>mid) return query(r[now],mid+1,y,ll,rr);
return query(l[now],x,mid,ll,rr)+query(r[now],mid+1,y,ll,rr);
}
int ask(int now,int x,int y,int ll,int rr)
{
if(!now) return 0;
if(ll<=x&&rr>=y) return d[now];
int mid=x+y>>1;
if(rr<=mid) return ask(l[now],x,mid,ll,rr);
if(ll>mid) return ask(r[now],mid+1,y,ll,rr);
return max(ask(l[now],x,mid,ll,rr),ask(r[now],mid+1,y,ll,rr));
}
inline int ask_sum(int x,int y,int col)
{
int s=0;
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]]) std::swap(x,y);
s+=query(rt[col],1,n,to[top[x]],to[x]);
x=fa[top[x]];
}
if(deep[x]>deep[y]) std::swap(x,y);
s+=query(rt[col],1,n,to[x],to[y]);
return s;
}
inline int ask_max(int x,int y,int col)
{
int s=0;
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]]) std::swap(x,y);
s=max(s,ask(rt[col],1,n,to[top[x]],to[x]));
x=fa[top[x]];
}
if(deep[x]>deep[y]) std::swap(x,y);
s=max(s,ask(rt[col],1,n,to[x],to[y]));
return s;
}
int main()
{
n=read(),Q=read();
for(re int i=1;i<=n;i++)
{
a[i]=read(),_[i]=read();
if(!rt[_[i]]) rt[_[i]]=++cnt;
}
int x,y;
for(re int i=1;i<n;i++)
x=read(),y=read(),add_edge(x,y),add_edge(y,x);
deep[1]=1,dfs1(1),dfs2(1,1);
for(re int i=1;i<=n;i++)
change(rt[c[i]],1,n,i,b[i]);
char opt[2];
int val;
while(Q--)
{
scanf("%s",opt);
if(opt[0]=='Q'&&opt[1]=='S')
{
x=read(),y=read();
printf("%d\n",ask_sum(x,y,_[x]));
}
if(opt[0]=='Q'&&opt[1]=='M')
{
x=read(),y=read();
printf("%d\n",ask_max(x,y,_[x]));
}
if(opt[0]=='C'&&opt[1]=='W')
{
x=read(),val=read();
b[to[x]]=val;
change(rt[_[x]],1,n,to[x],val);
}
if(opt[0]=='C'&&opt[1]=='C')
{
x=read(),val=read();
change(rt[val],1,n,to[x],b[to[x]]);
change(rt[_[x]],1,n,to[x],0);
_[x]=val;
}
}
return 0;
}

【[SDOI2014]旅行】的更多相关文章

  1. BZOJ 3531: [Sdoi2014]旅行 [树链剖分]

    3531: [Sdoi2014]旅行 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1685  Solved: 751[Submit][Status] ...

  2. 【BZOJ3531】[Sdoi2014]旅行 树链剖分+动态开点线段树

    [BZOJ3531][Sdoi2014]旅行 Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天 ...

  3. bzoj 3531 [Sdoi2014]旅行(树链剖分,线段树)

    3531: [Sdoi2014]旅行 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 876  Solved: 446[Submit][Status][ ...

  4. [SDOI2014]旅行

    洛谷 P3313 [SDOI2014]旅行 https://www.luogu.org/problem/show?pid=3313 题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接 ...

  5. B20J_3231_[SDOI2014]旅行_树链剖分+线段树

    B20J_3231_[SDOI2014]旅行_树链剖分+线段树 题意: S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,城市信仰不同的宗教,为了方便,我们用不同的正整数代表各种宗教. S国 ...

  6. [luogu P3313] [SDOI2014]旅行

    [luogu P3313] [SDOI2014]旅行 题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神 ...

  7. 洛谷 P3313 [SDOI2014]旅行 解题报告

    P3313 [SDOI2014]旅行 题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教 ...

  8. bzoj 3531 [Sdoi2014]旅行 (树剖+线段树 动态开点)

    3531: [Sdoi2014]旅行 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 2984  Solved: 1312[Submit][Status ...

  9. P3313 [SDOI2014]旅行

    P3313 [SDOI2014]旅行 树链剖分+动态线段树(并不是lct) 显然的,我们对于每一个宗教都要维护一个线段树. (那么空间不是爆炸了吗) 在这里引入:动态开点线段树 就是需要的点开起来,不 ...

  10. 3531: [Sdoi2014]旅行

    3531: [Sdoi2014]旅行 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 1731  Solved: 772 [Submit][Statu ...

随机推荐

  1. SQL Server Reporting Service(SSRS) 第七篇 常见错误汇总

    1. The current action cannot be completed. The user data source credentials do not meet the requirem ...

  2. 【CAD】创建多行文本

    下面为OBJECT-ARX创建多行文本的代码,记录 McDbMText* Mx::AddMText(IN McDbBlockTableRecord* pBlkRec, IN LPCTSTR pszCo ...

  3. FZU 2122 ——又见LKity——————【KMP字符串匹配】

    Problem 2122 又见LKity Accept: 413    Submit: 1425Time Limit: 1000 mSec    Memory Limit : 32768 KB  Pr ...

  4. django 将表数据通过API展示到页面上(转)

    需求: 我在learn这个app下创建了两张表,其中一个表为user,我希望通过API,在页面是展示这些数据,当用户访问指定的url时,将表中所有对象展示到页面上. 先看learn/models.py ...

  5. java File delete()执行失败原因(转)

    java.io.File里的delete操作很实用也很常用,可以用来删除单独的文件和某一目录.但有时候会出现delete失败的情况,出现这种情况的原因一般有以下几种:1.删除时还有其他程序在使用该文件 ...

  6. js 获取 Url.Action 设置area

    var url = '@Url.Action("UserEdit","User",new { Area = "Setup", id = 1} ...

  7. bootstrap清除数据源

    下拉框使用动态数据源,当下拉框触发change事件时,想让下拉框改变数据源,加了个if判断 $('#@idForCostCategory').change(function (event) { if( ...

  8. SpringSecurity 3.2入门(7)自定义权限控制介绍

    总结Spring Security的使用方法有如下几种: 一种是全部利用配置文件,将用户.权限.资源(url)硬编码在xml文件中. 二种是用户和权限用数据库存储,而资源(url)和权限的对应关系硬编 ...

  9. npm安装gulp-sass失败处理办法

    最近在做一个基于gulp的前端自动化的项目,在github上拉取代码后,按照正常的流程,首先我们要 npm  install ,在安装的过程中,一直提示我gulp-sass 安装失败,我用尽了好多办法 ...

  10. EF 取出demical数据,但需要去点小数,排序

    try { BasePaperWeightDAL.Get(o => o.IsDeleted == false && o.IsEnabled == true).OrderByDes ...