description

点击查看题目内容

solution

Step1
无脑建SAMSAMSAM
两个前缀的最长公共后缀就是parent−treeparent-treeparent−tree上两点的lcalcalca,定义知显然


Step2
离线询问,按右端点从小到大排序


Step3
每加入一个字母,就将tatata在parent−treeparent-treeparent−tree上到根节点的路径打上tatata的标记
如果遇到以前打的标记,则说明该节点即为旧标记与新标记的lcalcalca
贪心把标记覆盖为较大的值


Step4
树状数组统计
下标为左端点,每次查询下标大于等于该询问左端点的最大深度
向根跑的过程中每一次遇到旧标记,就在树状数组上更新答案,并给该节点打上新标记
但树状数组是用来计算前缀和的,所以有一个n−x+1n-x+1n−x+1的小转化


Step5
往根节点跑的过程即是LCTLCTLCT的accessaccessaccess操作


code

#include <cstdio>
#include <vector>
#include <iostream>
using namespace std;
#define maxn 200005
struct node {int f, val, tag;int son[2];
}tree[maxn];
struct SAM {int fa, len;int son[2];
}t[maxn];
vector < pair < int, int > > G[maxn];
int last = 1, cnt = 1, n, m;
char s[maxn];
int ans[maxn], maxx[maxn], num[maxn], st[maxn];int lowbit( int x ) {return x & ( -x );
}void modify( int x, int val ) {for( int i = n - x + 1;i <= n;i += lowbit( i ) )maxx[i] = max( maxx[i], val );
}int query( int x ) {int ans = 0;for( int i = n - x + 1;i;i -= lowbit( i ) )ans = max( ans, maxx[i] );return ans;
}void insert( int id, int x ) {int pre = last, now = last = ++ cnt;num[id] = cnt;t[now].len = t[pre].len + 1;while( pre && ! t[pre].son[x] ) t[pre].son[x] = now, pre = t[pre].fa;if( ! pre ) t[now].fa = 1;else {int u = t[pre].son[x];if( t[pre].len + 1 == t[u].len ) t[now].fa = u;else {int v = ++ cnt;t[v] = t[u];t[v].len = t[pre].len + 1;t[u].fa = t[now].fa = v;while( pre && t[pre].son[x] == u ) t[pre].son[x] = v, pre = t[pre].fa;}}
}bool isroot( int x ) {return tree[tree[x].f].son[0] == x || tree[tree[x].f].son[1] == x;
}void rotate( int x ) {int fa = tree[x].f, Gfa = tree[fa].f;int k = tree[fa].son[1] == x;if( isroot( fa ) )tree[Gfa].son[tree[Gfa].son[1] == fa] = x;tree[x].f = Gfa;if( tree[x].son[k ^ 1] )tree[tree[x].son[k ^ 1]].f = fa;tree[fa].son[k] = tree[x].son[k ^ 1];tree[x].son[k ^ 1] = fa;tree[fa].f = x;
}void change( int x, int val ) {tree[x].val = tree[x].tag = val;
}void pushdown( int x ) {if( ! tree[x].tag ) return;if( tree[x].son[0] ) change( tree[x].son[0], tree[x].tag );if( tree[x].son[1] ) change( tree[x].son[1], tree[x].tag );tree[x].tag = 0;
}void splay( int x ) {int Top = 0, y = x;st[++ Top] = y;while( isroot( y ) ) st[++ Top] = y = tree[y].f;while( Top ) pushdown( st[Top --] );while( isroot( x ) ) {int fa = tree[x].f, Gfa = tree[fa].f;if( isroot( fa ) )( ( tree[Gfa].son[0] == fa ) ^ ( tree[fa].son[0] == x ) ) ? rotate( x ) : rotate( fa );rotate( x );}
}void access( int x, int val ) {int son;for( son = 0;x;son = x, x = tree[x].f ) {splay( x );modify( tree[x].val, t[x].len );tree[x].son[1] = son;}tree[son].tag = tree[son].val = val;
}int main() {scanf( "%d %d %s", &n, &m, s + 1 );for( int i = 1;i <= n;i ++ ) //树状数组下标必须从1开始 insert( i, s[i] - '0' );for( int i = 1, l, r;i <= m;i ++ ) {scanf( "%d %d", &l, &r );G[r].push_back( make_pair( l, i ) );}for( int i = 1;i <= cnt;i ++ ) tree[i].f = t[i].fa;for( int i = 1;i <= n;i ++ ) {access( num[i], i );for( int j = 0;j < G[i].size();j ++ )ans[G[i][j].second] = query( G[i][j].first );}for( int i = 1;i <= m;i ++ )printf( "%d\n", ans[i] );return 0;
}

「雅礼集训 2017 Day7」事情的相似度(后缀自动机+LCT+树状数组)相关推荐

  1. [LOJ 6042]「雅礼集训 2017 Day7」跳蚤王国的宰相(树的重心+贪心)

    [LOJ 6042]「雅礼集训 2017 Day7」跳蚤王国的宰相 description solution 一个到所有节点距离和最小的节点 ⇔\Leftrightarrow⇔ 树的重心(满足最重的儿 ...

  2. 【思维题 细节】loj#6042. 「雅礼集训 2017 Day7」跳蚤王国的宰相

    挂于±1的细节-- 题目描述 跳蚤王国爆发了一场动乱,国王在镇压动乱的同时,需要在跳蚤国地方钦定一个人来做宰相. 由于当时形势的复杂性,很多跳蚤都并不想去做一个傀儡宰相,带着宰相的帽子,最后还冒着被打 ...

  3. 数据结构二之线段树Ⅱ——KiKi‘s K-Number,ball,The Child and Sequence,「雅礼集训 2017 Day1」市场,Atlantis

    值域线段树+势能线段树+扫描线 KiKi's K-Number ball The Child and Sequence 「雅礼集训 2017 Day1」市场 Atlantis KiKi's K-Num ...

  4. #6029. 「雅礼集训 2017 Day1」市场(势能,区间除)

    #6029. 「雅礼集训 2017 Day1」市场 用线段树维护数列,区间上维护最大最小值,区间和还有标记,修改时,区间加直接做,而区间除时,递归到线段树上某一区间,如果这一操作等价于区间加(也就是最 ...

  5. #6034. 「雅礼集训 2017 Day2」线段游戏 李超树

    #6034. 「雅礼集训 2017 Day2」线段游戏 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统 ...

  6. loj #6046. 「雅礼集训 2017 Day8」爷

    #6046. 「雅礼集训 2017 Day8」爷 题目描述 如果你对山口丁和 G&P 没有兴趣,可以无视题目背景,因为你估计看不懂 -- 在第 63 回战车道全国高中生大赛中,军神西住美穗带领 ...

  7. 「6月雅礼集训 2017 Day7」回转寿司

    [题目大意] 给一个n个数的序列,q次操作,每次选择区间$[l,r]$,给出数p,对于区间$[l,r]$的每个数$x$,做如下操作: 如果$x > p$,就交换$x$和$p$.求每次操作后$p$ ...

  8. LOJ#6044. 「雅礼集训 2017 Day8」共(Prufer序列)

    题面 传送门 题解 答案就是\(S(n-k,k)\times {n-1\choose k-1}\) 其中\(S(n,m)\)表示左边\(n\)个点,右边\(m\)个点的完全二分图的生成树个数,它的值为 ...

  9. LOJ#6048. 「雅礼集训 2017 Day10」数列(线段树)

    题面 传送门 题解 我的做法似乎非常复杂啊-- 首先最长上升子序列长度就等于把它反过来再接到前面求一遍,比方说把\(2134\)变成\(43122134\),实际上变化之后的求一个最长上升子序列和方案 ...

最新文章

  1. java中ssh如何理解
  2. python基础之内建函数(二)
  3. 在linux系统下安装两个nginx以及启动、停止、重起
  4. 解决算法问题的思路总结
  5. 具体数学-第4课(多重求和方法)
  6. (CVPR2019)视频-图像语义分割(21) 联合传播数据增广+标签松弛提升边界精度=语义分割效果提升
  7. 南京大学计算机学院冯新宇导师,中国科学技术大学计算机科学与技术专业硕士研究生导师冯新宇...
  8. java判断日文_java判断字符串是否中文、日文
  9. Sphinx速成指南
  10. 北京市工作居住证的申请与办理
  11. 基于Paddlehub实现的秒换证件照底色
  12. mysql连接查询和in的效率取舍
  13. 9个开源的 Vue3 组件库
  14. C# 调用 速印标签标准版 的模板lbl文件
  15. 新浪短链接API接口示例
  16. 202012-5 星际旅行
  17. Python数据结构之树形结构——数组存储
  18. 刷机风暴—3Q大战第二季
  19. 【超详细】Windows利用rclone将GoogleDrive等网盘/云盘挂载到本地
  20. 百度人工智能开源大赛784支团队角逐大奖

热门文章

  1. Google和百度都无法替代的10大深网搜索引擎
  2. python win7 sp1_[ Python - 15 ] win7安装paramiko问题总汇
  3. php 获取浏览器时区,获取用户时区
  4. python pp模块_Python模块--Pexpect
  5. python if elif else_python:通讯录(字典+while+if/else)
  6. java 创建以太坊代币_以太坊 (五)编写智能合约-建立简易加密代币
  7. java wrapper linux_Java Service Wrapper linux 服务 java 自启动
  8. cent os重置mysql,linux mysql 能登陆不能修改用户(cent os 6.2)解决思路
  9. 服务器不知道怎么回事安卓系统很卡,为什么安卓系统很容易变卡?该怎么解决?看完长知识了...
  10. c语言键盘控制数码管显示,3*4矩阵键盘控制4位数码管显示的C程序