链接

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

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

#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_backint 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;
}

转载于:https://www.cnblogs.com/HolyK/p/9835849.html

[LuoguU41039]PION后缀自动机 树链剖分+动态开点线段树相关推荐

  1. hdu3966 树链剖分点权模板+线段树区间更新/树状数组区间更新单点查询

    点权树的模板题,另外发现树状数组也是可以区间更新的.. 注意在对链进行操作时方向不要搞错 线段树版本 #include<bits/stdc++.h> using namespace std ...

  2. 动态开点线段树(多棵线段树)的内存分配与回收

    前言 线段树,是一个很好用的能支持O(logn)区间操作的数据结构,随着做一些稍微烦一点的题,有时候会发现有些情况要开一个数组的线段树,更有甚者要树套树,而在很多情况下线段树就不能把所有点都开满了(否 ...

  3. 树链剖分(bzoj 1036: [ZJOI2008]树的统计Count)

    树链剖分: 把一棵树剖分为若干条链,然后利用数据结构(树状数组,SBT,Splay,线段树等等)去维护每一条链,复杂度 为O(logn),总体复杂度O(nlog²n) 步骤: ①将树的边分成重边和轻边 ...

  4. NOIP2017 列队——动态开点线段树

    Description: Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n×m名学生,方阵的行数为  ...

  5. 【线段树合并】解题报告:luogu P4556雨天的尾巴 (树上对点差分 + 动态开点 + 线段树合并)线段树合并模板离线/在线详解

    题目链接:雨天的尾巴 本题本身是一个非常简单的一道树上差分的模板题,但是由于变态的数据范围,我们直接用数组是存不下的(本来使用一颗普通的线段树直接维护最大值即可.但是本题的空间只有128MB,直接按照 ...

  6. 洛谷P3960 列队(动态开节点线段树)

    题意 题目链接 Sol 看不懂splay..,看不懂树状数组... 只会暴力动态开节点线段树 观察之后不难发现,我们对于行和列需要支持的操作都是相同的:找到第\(k\)大的元素并删除,在末尾插入一个元 ...

  7. CF1045G AI robots(动态开点线段树)

    题意 火星上有$N$个机器人排成一行,第$i$个机器人的位置为$x_{i}$,视野为$r_{i}$,智商为$q_{i}$.我们认为第$i$个机器人可以看到的位置是$[x_{i}-r_{i},x_{i} ...

  8. codeforces 915E - Physical Education Lessons 动态开点线段树

    题意: 最大$10^9$的区间, $3*10^5$次区间修改,每次操作后求整个区间的和 题解: 裸的动态开点线段树,计算清楚数据范围是关键... 经过尝试 $2*10^7$会$MLE$ $10^7$会 ...

  9. HDU 6681 Rikka with Cake(扫描线、动态开点线段树)

    http://acm.hdu.edu.cn/showproblem.php?pid=6681 题意 在矩形区域内有k条射线,问这些射线将矩形分成了多少区域 题解 容易发现答案为所有射线交点个数+1. ...

最新文章

  1. 目标检测--Improving Object Detection With One Line of Code
  2. vb检测电脑温度_电脑硬件温度多少正常?如何查看电脑硬件温度?
  3. MySQL流浪记(四)—— DDL和DML区别与介绍
  4. 北大信科学院实验室_从实验室科学家到开放科学软件开发人员
  5. python游戏编程快速上手豆瓣_Python游戏编程快速上手(第4版)
  6. poj 3714 Raid
  7. python 会议室预约系统解决方案_智能会议预约系统解决方案
  8. 在北京买车可以上外地牌照吗
  9. FPGA是什么呢,通透讲解单片机和FPGA的区别
  10. CNCC技术论坛|分布式数据库HTAP的探索与实践
  11. jdk8特性 lambda表达式
  12. 无线通信———比较射频和蜂窝电话
  13. 安搭Share为您推荐学理财投资必读的书籍
  14. crontab服务启动 停止 重启(linux 定时任务)
  15. 市场主流性能测试工具简介
  16. JVM 对 Java 的原生锁做了哪些优化?
  17. 如何计算某年某月有多少天?
  18. 计算机加密恢复,系统小技巧:BitLocker密钥恢复二三事
  19. 小心 base64 编码数据拖慢你的后台服务
  20. ssm基于Java和MySql的产业信息管理系统的设计与实现毕业设计源码260839

热门文章

  1. 胡阳pyhton作业题--20150728
  2. 荣耀8X成为全球首款通过TUV莱茵低蓝光认证的手机
  3. STM32之时钟输出功能
  4. ios链接xcode跑自动化意外中断?可以用pyautogui试试
  5. 用turtle画只小熊猫
  6. php中根据二维数组某个字段的值查找对应的一维数组
  7. 周周有惊喜奖,第三期开奖名单 --2007中国软件开发者大调查
  8. 深度学习的归一化和反归一化
  9. PHP教程电子版下载
  10. ballerina 学习二十八 快速grpc 服务开发