bzoj 3881 [Coci2015]Divljak——LCT维护parent树链并

博客围绕题目 https://www.lydsy.com/JudgeOnline/problem.php?id=3881 展开,提到对 S 建 SAM ,每个 T 会使 S 的 parent 树的链并答案加 1。在 T 移动时用 LCT access 找链并打标记,若遇到已标记点则停止 access ,实现时判断 fa[x] 标记前要先 splay(fa[x]) 。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3881

对 S 建 SAM ,每个 T 会让 S 的 parent 树的链并答案+1;在 T 走每一步的时候,走到的节点用 LCT access 一下,就能找到该点到 parent 根的链。

给链打标记。在 access 的过程中,如果遇到已经打过这个 T 标记的点,就停止 access 。

注意实现的时候,在判断 fa[x] 有没有标记之前要先 splay(fa[x]) 。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ls c[cr][0]
#define rs c[cr][1]
using namespace std;
int rdn()
{
  int ret=0;bool fx=1;char ch=getchar();
  while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
  while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
  return fx?ret:-ret;
}
const int N=1e5+5,M=2e6+5,K=26;
int n,ps[N],tot=1,c[M][K],tc[M][K],fl[M],q[M];
int tim,dfn[M],fa[M],vl[M],tg[M],sta[M];
char s[M];
bool isrt(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;}
void cz(int cr)
{
  if(!tg[cr])return; int w=tg[cr];tg[cr]=0;
  vl[ls]+=w; vl[rs]+=w;
  tg[ls]+=w; tg[rs]+=w;
  dfn[ls]=dfn[rs]=dfn[cr];///
}
void rotate(int x)
{
  int y=fa[x],z=fa[y],d=(x==c[y][1]);
  if(!isrt(y))c[z][y==c[z][1]]=x;
  fa[x]=z; fa[y]=x; fa[c[x][!d]]=y;
  c[y][d]=c[x][!d]; c[x][!d]=y;
}
void splay(int x)
{
  int top; sta[top=1]=x;
  for(int k=x;!isrt(k);k=fa[k])sta[++top]=fa[k];
  for(int i=top;i;i--)cz(sta[i]);
  for(int y=fa[x],z=fa[y];!isrt(x);rotate(x),y=fa[x],z=fa[y])
    if(!isrt(y))
      ((y==c[z][0])^(x==c[y][0]))?rotate(x):rotate(y);
}
void access(int x)
{
  splay(x); if(dfn[x]==tim)return;
  int t=0;
  while(1)
    {
      c[x][1]=t;
      if(!fa[x])
    { tg[x]++;vl[x]++;dfn[x]=tim;return;}
      splay(fa[x]);//splay first
      if(dfn[fa[x]]==tim)
    { tg[x]++;vl[x]++;dfn[x]=tim;return;}
      t=x; x=fa[x];
    }
}
void link(int x,int y){ fa[y]=x;}
int Ins()
{
  int cr=1,len=strlen(s+1);
  for(int i=1;i<=len;i++)
    {
      int w=s[i]-'a';
      if(!tc[cr][w])tc[cr][w]=++tot;
      cr=tc[cr][w];
    }
  return cr;
}
void get_fl()
{
  int he=0,tl=0;
  for(int i=0,v;i<K;i++)
    if((v=tc[1][i]))
      {q[++tl]=v;fl[v]=1;link(1,v);}
    else tc[1][i]=1;
  while(he<tl)
    {
      int k=q[++he],pr=fl[k];
      for(int i=0,v;i<K;i++)
    if((v=tc[k][i]))
      { q[++tl]=v;fl[v]=tc[pr][i];link(tc[pr][i],v);}
    else tc[k][i]=tc[pr][i];
    }
}
void solve()
{
  tim++; int cr=1,len=strlen(s+1);
  for(int i=1;i<=len;i++)
    {
      cr=tc[cr][s[i]-'a'];
      access(cr);
    }
}
int main()
{
  n=rdn();
  for(int i=1;i<=n;i++)
    { scanf("%s",s+1); ps[i]=Ins();}
  get_fl();
  int Q=rdn(),op,x;
  while(Q--)
    {
      op=rdn();
      if(op==1)
    { scanf("%s",s+1); solve();}
      else
    {
      x=rdn(); x=ps[x];
      splay(x); printf("%d\n",vl[x]);
    }
    }
  return 0;
}

 

转载于:https://www.cnblogs.com/Narh/p/10804518.html

一、综合实战—使用极轴追踪方式绘制信号灯 实战目标:利用对象捕捉追踪和极轴追踪功能创建信号灯图形 技术要点:结合两种追踪方式实现精确绘图,适用于工程制图中需要精确定位的场景 1. 切换至AutoCAD 操作步骤: 启动AutoCAD 2016软件 打开随书光盘中的素材文件 确认工作空间为"草图与注释"模式 2. 绘图设置 1)草图设置对话框 打开方式:通过"工具→绘图设置"菜单命令 功能定位:该对话框包含捕捉、追踪等核心绘图辅助功能设置 2)对象捕捉设置 关键配置: 启用对象捕捉(F3快捷键) 启用对象捕捉追踪(F11快捷键) 勾选端点、中心、圆心、象限点等常用捕捉模式 追踪原理:命令执行时悬停光标可显示追踪矢量,再次悬停可停止追踪 3)极轴追踪设置 参数设置: 启用极轴追踪功能 设置角度增量为45度 确认后退出对话框 3. 绘制信号灯 1)绘制圆形 执行命令:"绘图→圆→圆心、半径"命令 绘制过程: 使用对象捕捉追踪定位矩形中心作为圆心 输入半径值30按Enter确认 通过象限点捕捉确保圆形位置准确 2)绘制直线 操作要点: 选择"绘图→直线"命令 捕捉矩形上边中点作为起点 捕捉圆的上象限点作为终点 按Enter结束当前直线命令 重复技巧: 按Enter可重复最近使用的直线命令 通过圆心捕捉和极轴追踪绘制放射状直线 最终形成完整的信号灯指示图案 3)完成绘制 验证要点: 检查所有直线是否准确连接圆心和象限点 确认极轴追踪的45度增量是否体现 保存绘图文件(快捷键Ctrl+S)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值