LOJ

被一件不愉快的小事浪费了一个小时= =。

表示自己(OI方面的)智商没救了=-=


比较显然 二分+树哈希。考虑对树的括号序列进行哈希。

那么每个点的\(k\)子树的括号序列,就是一段区间去掉距离它为\(k+1\)的点的子树的区间。那么我们把每个点放到它的\(k+1\)级祖先上,在\(k+1\)级祖先处求哈希值时,跳过这个点的括号区间即可。

至于具体的哈希方式...xjb哈希就行了


//672ms	24.97M
#include <cstdio>
#include <cctype>
#include <vector>
#include <algorithm>
#include <unordered_map>
#define seed 193
#define gc() getchar()
#define MAXIN 500000
//#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
typedef unsigned long long ull;
const int N=1e5+5,M=N<<1; int H[N],nxt[N],L[N],R[N],A[M],mxdep[N];
ull pw[M],hs[M];
std::vector<int> vec[N];
std::unordered_map<ull,bool> vis[18];
char IN[MAXIN],*SS=IN,*TT=IN; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-48,c=gc());
return now;
}
inline void AE(int u,int v)
{
nxt[v]=H[u], H[u]=v;
}
inline ull Hash(int l,int r)
{
return hs[r]-pw[r-l+1]*hs[l-1];
}
void DFS1(int x)
{
static int Index=0;
A[L[x]=++Index]=97; int mx=0;
for(int v=H[x]; v; v=nxt[v]) DFS1(v), mx=std::max(mx,mxdep[v]);
A[R[x]=++Index]=131, mxdep[x]=mx+1;
}
bool DFS2(int x,int k,std::unordered_map<ull,bool> &vis)
{
static int top,sk[N];
sk[++top]=x, std::vector<int>().swap(vec[x]);
if(top>k+1) vec[sk[top-k-1]].push_back(x);
for(int v=H[x]; v; v=nxt[v])
if(DFS2(v,k,vis)) return --top,1;
--top;
if(mxdep[x]<=k) return 0;
int l=L[x],r; ull val=0;
for(auto v:vec[x]) r=L[v]-1, val=val*pw[r-l+1]+Hash(l,r), l=R[v]+1;
r=R[x], val=val*pw[r-l+1]+Hash(l,r);
return vis.count(val)?1:(vis[val]=1,0);
} int main()
{
const int n=read(),n2=n<<1;
for(int i=1; i<=n; ++i)
for(int t=read(); t--; AE(i,read()));//reverse
DFS1(1), pw[0]=1;
for(int i=1; i<=n2; ++i) pw[i]=pw[i-1]*seed, hs[i]=hs[i-1]*seed+A[i];
int l=1,r=n-1,mid,ans=0,t=0;
while(l<=r) DFS2(1,mid=l+r>>1,vis[t++])?(ans=mid,l=mid+1):r=mid-1;
printf("%d\n",ans); return 0;
}

LOJ.6066.[2017山东一轮集训Day3]第二题(树哈希 二分)的更多相关文章

  1. 【LOJ#6066】「2017 山东一轮集训 Day3」第二题(哈希,二分)

    [LOJ#6066]「2017 山东一轮集训 Day3」第二题(哈希,二分) 题面 LOJ 题解 要哈希是很显然的,那么就考虑哈希什么... 要找一个东西可以表示一棵树,所以我们找到了括号序列. 那么 ...

  2. 【LOJ6067】【2017 山东一轮集训 Day3】第三题 FFT

    [LOJ6067][2017 山东一轮集训 Day3]第三题 FFT 题目大意 给你 \(n,b,c,d,e,a_0,a_1,\ldots,a_{n-1}\),定义 \[ \begin{align} ...

  3. [LOJ#6066]. 「2017 山东一轮集训 Day3」第二题[二分+括号序列+hash]

    题意 题目链接 分析 首先二分,假设二分的答案为 \(mid\),然后考虑利用括号序列来表示树的形态. 点 \(u\) 的 \(k-\) 子树的括号序列表示实际上是刨去了 \(u\) 子树内若干个与 ...

  4. LOJ.6060.[2017山东一轮集训Day1/SDWC2018Day1]Set(线性基)

    LOJ BZOJ 明明做过一道(最初思路)比较类似的题啊,怎么还是一点思路没有. 记所有元素的异或和为\(s\),那么\(x_1+x_2=x_1+x_1\ ^{\wedge}s\). \(s\)是确定 ...

  5. loj#6073. 「2017 山东一轮集训 Day5」距离(树链剖分 主席树)

    题意 题目链接 Sol 首先对询问差分一下,我们就只需要统计\(u, v, lca(u, v), fa[lca(u, v)]\)到根的路径的贡献. 再把每个点与\(k\)的lca的距离差分一下,则只需 ...

  6. LOJ.6073.[2017山东一轮集训Day5]距离(可持久化线段树 树链剖分)

    题目链接 就是恶心人的,简单写写了...(似乎就是[HNOI2015]开店?) 拆式子,记\(dis_i\)为\(i\)到根节点的路径权值和,\(Ans=\sum dis_{p_i}+\sum dis ...

  7. LOJ.6074.[2017山东一轮集训Day6]子序列(DP 矩阵乘法)

    题目链接 参考yww的题解.本来不想写来但是他有一些笔误...而且有些地方不太一样就写篇好了. 不知不觉怎么写了这么多... 另外还是有莫队做法的...(虽然可能卡不过) \(60\)分的\(O(n^ ...

  8. LOJ.6068.[2017山东一轮集训Day4]棋盘(费用流zkw)

    题目链接 考虑两个\(\#\)之间产生的花费是怎样的.设这之间放了\(k\)个棋子,花费是\(\frac{k(k-1)}{2}\). 在\((r,c)\)处放棋子,行和列会同时产生花费,且花费和该行该 ...

  9. LOJ.6062.[2017山东一轮集训]Pair(Hall定理 线段树)

    题目链接 首先Bi之间的大小关系没用,先对它排序,假设从小到大排 那么每个Ai所能匹配的Bi就是一个B[]的后缀 把一个B[]后缀的匹配看做一条边的覆盖,设Xi为Bi被覆盖的次数 容易想到 对于每个i ...

随机推荐

  1. mongodb增加新字段报错解决方法

    今天想在项目的一个集合里增加一个新字段 db.article.update({},{$set:{status:0}},{multi:true}) multi : 可选,mongodb 默认是false ...

  2. windows service创建使用整合

    C#创建Windows Service(Windows 服务)基础教程 C#winform windows服务程序创建与安装 C#实现WinForm随WINDOWS服务一起启动

  3. mac air中编译安装swoole

    本机php版本, 我的7.3.0 1 下载swoole源码 https://github.com/swoole/swoole-src/releases 我下载的版本是swoole-src-4.3.3. ...

  4. 从Word Embedding到Bert模型—自然语言处理中的预训练技术发展史(转载)

    转载 https://zhuanlan.zhihu.com/p/49271699 首发于深度学习前沿笔记 写文章   从Word Embedding到Bert模型—自然语言处理中的预训练技术发展史 张 ...

  5. twfont

    module game { /** *Created by 渔歌烟火 on 2018/3/28. * 字体缓动动画 */ export class LabelEffect { private stat ...

  6. vo类,model类,dto类的作用及划分

    1.entity里的每一个字段,与数据库相对应, 2.dto里的每一个字段,是和你前台页面相对应, 3.VO,这是用来转换从entity到dto,或者从dto到entity的中间的东西.   举个例子 ...

  7. 编写ROS程序--HelloROS

    <机器人操作系统浅析>ch3学习记录 A Gentle Introduction to ROS 3.1 创建工作区(工作空间)和功能包 创建工作空间 ~/ros 我们称之为工作区目录 在工 ...

  8. git知识总结-1.git基础之数据存储

    1.前言 git包含四种对象文件: blob tree commit tag(目前没用到,暂时忽略) 2. git对象的关系   图 git三种对象关系   粗略一看,可以大致感觉出blob类似于文件 ...

  9. mysql插入大数据

    /*部门表*/ CREATE TABLE dept( id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, /*id*/ deptno MEDIUMINT UNSIG ...

  10. Python 并发编程

    进程 开启进程 from multiprocessing import Process import time def task(name): print('%s is running' %name) ...