链接

刚开始看出题人题解都吓蒙掉了,还以为是什么难题,结果就一板子题

思路:对每一个文件名开一棵线段树,然后树剖即可

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i(a);i<=(b);++i)
#define dbg(...) fprintf(stderr,__VA_ARGS__)
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int>pii;
template<typename T,typename U>inline char smin(T&x,const U&y){return x>y?x=y,1:0;}
template<typename T,typename U>inline char smax(T&x,const U&y){return x<y?x=y,1:0;}
int T;
struct hash_table{
static const int S=1e6+5;
int head[S],to[S],ne[S];
inline int get(char *s){
int u=0;while(*s)u=u*27+*s++-'a'+1;int p=u%S;
for(int i=head[p];i;i=ne[i])if(to[i]==u)return i;
to[++T]=u,ne[T]=head[p],head[p]=T;
return T;
}
}mp;
const int N=1e5+5,MT=5e5+5;
int n,m;
vector<int>g[N];
int fa[N],dep[N],top[N],in[N],son[N],siz[N],dfn;
inline void go1(int x){
siz[x]=1;
for(int y:g[x])if(y!=fa[x])
dep[y]=dep[x]+1,fa[y]=x,go1(y),siz[x]+=siz[y],siz[y]>siz[son[x]]&&(son[x]=y);
}
inline void go2(int x,int anc){
in[x]=++dfn,top[x]=anc;
if(!son[x])return;go2(son[x],anc);
for(int y:g[x])if(y!=fa[x]&&y!=son[x])go2(y,y);
}
inline int dis(int x,int y){
int ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans+=dep[x]-dep[top[x]]+1;x=fa[top[x]];
}
return ans+abs(dep[x]-dep[y]);
}
int rt[MT],treecnt;
struct tree{int ls,rs,w;bool del;}t[MT*25];
inline void ins(int&o,int l,int r,int x){
if(!o)o=++treecnt;++t[o].w;
if(l==r)return;int mid=l+r>>1;
x<=mid?ins(t[o].ls,l,mid,x):ins(t[o].rs,mid+1,r,x);
}
inline void pushdown(int o){
if(t[o].del){
if(t[o].ls)t[t[o].ls].w=0,t[t[o].ls].del=1;
if(t[o].rs)t[t[o].rs].w=0,t[t[o].rs].del=1;
t[o].del=0;
}
}
inline int ask(int o,int l,int r,int x,int y){
if(!o||x>r||y<l||x>y||t[o].del)return 0;
if(x<=l&&r<=y)return t[o].w;pushdown(o);
int mid=l+r>>1;
return ask(t[o].ls,l,mid,x,y)+ask(t[o].rs,mid+1,r,x,y);
}
inline int update(int o,int l,int r,int x,int y){
if(!o||x>y||t[o].del)return 0;
if(x<=l&&r<=y){
int res=t[o].w;t[o].w=0;t[o].del=1;return res;
}
int mid=l+r>>1,res=0;pushdown(o);
if(x<=mid)res+=update(t[o].ls,l,mid,x,y);
if(y>mid)res+=update(t[o].rs,mid+1,r,x,y);
t[o].w=t[t[o].ls].w+t[t[o].rs].w;
return res;
}
inline int ask(int o,int x,int y){
int ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans+=ask(o,1,n,in[top[x]],in[x]);x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
return ans+ask(o,1,n,in[x],in[y]);
}
inline int update(int o,int x,int y){
int ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans+=update(o,1,n,in[top[x]],in[x]);x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
return ans+update(o,1,n,in[x],in[y]);
}
int main(){
scanf("%d%d",&n,&m);
REP(i,2,n){
#define pb push_back
int x,y;scanf("%d%d",&x,&y);g[x].pb(y),g[y].pb(x);
}
go1(1),go2(1,1);
static char s[10];
REP(i,1,n){
int t;scanf("%d",&t);
while(t--){
scanf("%s",s);
ins(rt[mp.get(s)],1,n,in[i]);
}
}
while(m--){
scanf("%s",s);
int x,y;
if(s[0]=='q'){
scanf("%s%d%d",s,&x,&y);
if(s[1]=='p')printf("%d\n",dis(x,y));
else{
scanf(" *.%s",s);printf("%d\n",ask(rt[mp.get(s)],x,y));
}
}else{
scanf("%*s%d%d *.%s",&x,&y,s);
printf("%d\n",update(rt[mp.get(s)],x,y));
}
}
return 0;
}

[LuoguU41039]PION后缀自动机 树链剖分+动态开点线段树的更多相关文章

  1. 【bzoj4999】This Problem Is Too Simple! 树链剖分+动态开点线段树

    题目描述 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: 1. C i x(0<=x<2^31) 表示将i节点的值改为x. 2. Q i j x(0<=x<2^31) ...

  2. [bzoj 3531][SDOI2014]旅行(树链剖分+动态开点线段树)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3531 分析: 对于每个颜色(颜色<=10^5)都建立一颗线段树 什么!那么不是M ...

  3. 洛谷P3313 [SDOI2014]旅行(树链剖分 动态开节点线段树)

    题意 题目链接 Sol 树链剖分板子 + 动态开节点线段树板子 #include<bits/stdc++.h> #define Pair pair<int, int> #def ...

  4. BZOJ 3531 [Sdoi2014]旅行 树链剖分+动态开点线段树

    题意 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. 为了方便,我们用 ...

  5. bzoj3531: [Sdoi2014]旅行 (树链剖分 && 动态开点线段树)

    感觉动态开点线段树空间复杂度好优秀呀 树剖裸题 把每个宗教都开一颗线段树就可以了 但是我一直TLE 然后调了一个小时 为什么呢 因为我 #define max(x, y) (x > y ? x ...

  6. [ZJOI2019]语言(树链剖分+动态开点线段树+启发式合并)

    首先,对于从每个点出发的路径,答案一定是过这个点的路径所覆盖的点数.然后可以做树上差分,对每个点记录路径产生总贡献,然后做一个树剖维护,对每个点维护一个动态开点线段树.最后再从根节点开始做一遍dfs, ...

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

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

  8. BZOJ4999: This Problem Is Too Simple!树链剖分+动态开点线段树

    题目大意:将某个节点的颜色变为x,查询i,j路径上多少个颜色为x的点... 其实最开始一看就是主席树+树状数组+DFS序...但是过不去...MLE+TLE BY FCWWW 其实树剖裸的一批...只 ...

  9. bzoj3531——树链剖分+动态开点线段树

    3531: [Sdoi2014]旅行 Time Limit: 20 Sec  Memory Limit: 512 MB Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连 ...

随机推荐

  1. Quart 学习

    quartz版本使用2.2.1 梳理一下其中的流程,可以表示为: 0.调度器线程run() 1.获取待触发trigger 1.1数据库LOCKS表TRIGGER_ACCESS行加锁 1.2读取JobD ...

  2. HDU 5379 Mahjong tree dfs+组合数学

    题意:给你一棵树来分配号码,要求是兄弟节点连续并且每一棵子树连续. 思路:因为要求兄弟和子树都是连续的,所以自己打下草稿就可以发现如果一个节点有3个或3个以上的非叶子结点,那么就无论如何也不能达到目的 ...

  3. Design Pattern - Service Locator Pattern--转载

    原文地址:http://www.tutorialspoint.com/design_pattern/service_locator_pattern.htm The service locator de ...

  4. asp.net 关于cookie的操作

    一.无子键或单级cookie 读写(1).写入: 第一种 HttpCookie cookie=new HttpCookie("User"); cookie.Value=" ...

  5. openSUSE Leap与 SELS的区别

    openSUSE Leap 是 openSUSE 常规发行版本的新名称,在 13.2 之前它仅仅被称为“openSUSE”. 一.openSUSE 发行周期:(15年以前仅有一个openSUSE发行版 ...

  6. 紫书 习题 10-16 UVa 1647 (高精度+递推)

    这道题我已经推出00和1过两步变成00了,可我没有继续做下去-- 后来看了博客发现自己已经做了90%了-- 可惜了,以后不要轻易放弃. 1的个数有个规律,就是每次都乘以2,因为0和1下一步都会变出1 ...

  7. 【Tika基础教程之中的一个】Tika基础教程

    一.高速入门 1.Tika是一个用于文本解释的框架.其本身并不提供不论什么的库用于解释文本,而是调用各种各样的库,如POI,PDFBox等. 使用Tika.能够提取文件里的作者.标题.创建时间.正文等 ...

  8. 整合struts2+spring+hibernate

     一.准备struts2+spring+hibernate所须要的jar包:        新建web项目并将jar包引入到project项目中. 二.搭建struts2环境        a.在 ...

  9. Android Studio升级到0.8.1后怎样设置字体大小?

    升级到0.8.1后.打开设置字体大小页面.你会发现无论是Default还是Darcula,都不同意你改变字体的大小.事实上这个是由于这两个模式是Android Studio自带模式,所以不同意你修改, ...

  10. vim基础学习之自动补全功能

    本章我们学习自动补全功能1.自动补全优先从当前的编辑区获得补全列表例如:我们写下如下内容 aaaaa aabbb aaab 当我们再次输入aa,然后我们按下Tab的时候,会弹出一个包含 aaaaa a ...