清橙A1484
http://www.tsinsen.com/ViewGProblem.page?gpid=A1484###
题解:
在线插入并不好做,我们将所有操作离线,变为删除操作。
每次询问的时候对于当前B串所在起始位置及其长度向上向下二分,然后查询区间内合法的当前A串内的匹配点即可。
用树状数组维护(不过我sb的写了线段树,后来才发现···)。
code:
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#define maxn 200005
using namespace std;
char ch,a[maxn*],b[maxn*],s[maxn];
int n,m,q,la,ra,lb,rb,lena,lenb,op[maxn],st[][maxn],ans[maxn];
int SA[maxn],rank[maxn],sum[maxn],height[maxn],t1[maxn],t2[maxn];
bool ok;
void read(int &x){
for (ok=,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=;
for (x=;isdigit(ch);x=x*+ch-'',ch=getchar());
if (ok) x=-x;
}
struct seg{
#define ls k<<1
#define rs (k<<1)+1
int val[maxn<<];
void build(int k,int l,int r){
if (l==r){
if (SA[l]<=ra) val[k]=;
return;
}
int m=(l+r)>>;
build(ls,l,m),build(rs,m+,r);
val[k]=val[ls]+val[rs];
}
void modify(int k,int l,int r,int x,int add){
if (l==r){val[k]+=add;return;}
int m=(l+r)>>;
if (x<=m) modify(ls,l,m,x,add);
else modify(rs,m+,r,x,add);
val[k]=val[ls]+val[rs];
}
int query(int k,int l,int r,int x,int y){
if (l==x&&r==y) return val[k];
int m=(l+r)>>;
if (y<=m) return query(ls,l,m,x,y);
else if (x<=m) return query(ls,l,m,x,m)+query(rs,m+,r,m+,y);
else return query(rs,m+,r,x,y);
}
}T;
void get_SA(){
int *x=t1,*y=t2,tot=; m=;
for (int i=;i<=n;i++) sum[x[i]=s[i]]++;
for (int i=;i<=m;i++) sum[i]+=sum[i-];
for (int i=n;i>=;i--) SA[sum[x[i]]--]=i;
for (int len=;tot<n;len<<=,m=tot){
tot=;
for (int i=n-len+;i<=n;i++) y[++tot]=i;
for (int i=;i<=n;i++) if (SA[i]>len) y[++tot]=SA[i]-len;
for (int i=;i<=m;i++) sum[i]=;
for (int i=;i<=n;i++) sum[x[y[i]]]++;
for (int i=;i<=m;i++) sum[i]+=sum[i-];
for (int i=n;i>=;i--) SA[sum[x[y[i]]]--]=y[i];
swap(x,y),x[SA[]]=tot=;
for (int i=;i<=n;i++){
if (y[SA[i]]!=y[SA[i-]]||y[SA[i]+len]!=y[SA[i-]+len]) tot++;
x[SA[i]]=tot;
}
}
for (int i=;i<=n;i++) rank[i]=x[i];
}
void get_height(){
for (int i=,j=;i<=n;i++){
if (rank[i]==) continue;
while (s[i+j]==s[SA[rank[i]-]+j]) j++;
height[rank[i]]=j;
if (j>) j--;
}
}
void prepare(){
for (int i=;i<=n;i++) st[][i]=height[i];
for (int i=;i<=;i++)
for (int j=;j<=n;j++){
st[i][j]=st[i-][j];
if (j+(<<(i-))<=n) st[i][j]=min(st[i][j],st[i-][j+(<<(i-))]);
}
T.build(,,n);
}
int calc(int l,int r){
if (l>r) swap(l,r);
int t=; l++;
if (l==r) return height[l];
for (;l+(<<t)<r;t++);
if (l+(<<t)>r) t--;
return min(st[t][l],st[t][r-(<<t)+]);
}
int find(int s,int x,int op){
int l,r,m;
if (op) l=s,r=n;else l=,r=s;
while (l!=r){
m=((l+r)>>)+op;
if (calc(m,s)<x){
if (op) r=m-;
else l=m+;
}
else{
if (op) l=m;
else r=m;
}
}
return l;
}
int query(){
int x=find(rank[lb],rb-lb+,),y=find(rank[lb],rb-lb+,);
return T.query(,,n,x,y);
}
int main(){
scanf("%s%s",a+maxn,b+maxn);
la=ra=maxn,lb=rb=maxn;
for (;a[ra];ra++); ra--;
for (;b[rb];rb++); rb--;
read(q);
for (int i=;i<=q;i++){
read(op[i]);
if (op[i]==) a[--la]=getchar();
else if (op[i]==) a[++ra]=getchar();
else if (op[i]==) b[--lb]=getchar();
else if (op[i]==) b[++rb]=getchar();
}
for (int i=la;i<=ra;i++) s[++n]=a[i];
lena=ra-la+,la=,ra=lena;
s[++n]='#';
int tmp=n+;
lenb=rb-lb+;
for (int i=lb;i<=rb;i++) s[++n]=b[i];
lb=tmp,rb=lb+lenb-;
get_SA(),get_height(),prepare();
for (int i=;i<lenb;i++) T.modify(,,n,rank[ra--],-);
for (int i=q;i>=;i--){
if (op[i]==) T.modify(,,n,rank[la++],-);
else if (op[i]==) T.modify(,,n,rank[ra--],-);
else if (op[i]==) T.modify(,,n,rank[++ra],),lb++;
else if (op[i]==) T.modify(,,n,rank[++ra],),rb--;
else ans[i]=query();
}
for (int i=;i<=q;i++) if (op[i]==) printf("%d\n",ans[i]);
return ;
}
清橙A1484的更多相关文章
- 清橙A1212:剪枝
题面 清橙 Sol 一种新的树上\(DP\)姿势 从左往右按链\(DP\) 做法: 维护两个栈\(S1\),\(S2\) \(S1\)存当前的链 \(S2\)存分叉点以下要改的链 \(Dfs\),弄一 ...
- 清橙A1202&Bzoj2201:彩色圆环
因为Bzoj是权限题,所以可以去清橙做一下 Sol 突然考了一道这样的题,考场上强行\(yy\)出来了 win下评测Long double爆零TAT 首先肯定是破环为链变成序列问题辣 那么就要求第一个 ...
- [清橙A1210]光棱坦克
[清橙A1210]光棱坦克 题目大意: 平面上放置了\(n(n\le7000)\)个反射装置,光纤将从某个装置出发,在经过一处装置时发生反射,若经过的装置坐标依次为\((x_1,y_1),(x_2,y ...
- 清橙A1206.小Z的袜子 && CF 86D(莫队两题)
清橙A1206.小Z的袜子 && CF 86D(莫队两题) 在网上看了一些别人写的关于莫队算法的介绍,我认为,莫队与其说是一种算法,不如说是一种思想,他通过先分块再排序来优化离线查询问 ...
- 洛谷 P1903 BZOJ 2120 清橙 A1274【模板】分块/带修改莫队(数颜色)(周奕超)
试题来源 2011中国国家集训队命题答辩 题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔 ...
- 清橙 A1206 小Z的袜子(莫队算法)
A1206. 小Z的袜子 时间限制:1.0s 内存限制:512.0MB 总提交次数:1357 AC次数:406 平均分:46.75 将本题分享到: 查看未格式化的试题 ...
- 清橙A1363. 水位 - 清华大学2012年信息学优秀高中学子夏令营
问题描述 有一个正方形的地区,该地区特点鲜明:如果把它等分为N×N个小正方形格子的话,在每个格子内的任意地点的地表高度是相同的,并且是一个0到M之间的整数.正方形地区的外部被无限高的边界包围. 该地区 ...
- 清橙 A1120 拦截导弹 -- 动态规划(最长上升子序列)
题目地址:http://oj.tsinsen.com/A1120 问题描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但 ...
- 清橙OJ 1082 查找第K小元素 -- 快速排序
题目地址:http://oj.tsinsen.com/A1082 问题描述 给定一个大小为n的数组s和一个整数K,请找出数组中的第K小元素. 这是一个补充程序的试题,你需要完成一个函数: int fi ...
随机推荐
- python 代码格式化工具:autopep8
学习资料: https://github.com/hhatto/autopep8 背景 autopep8 会根据 PEP 8 样式文档来格式化 python 代码.它使用 pep8 来决定代码的哪部分 ...
- Java实现人民币大写代码解析
想要实现人民币大写,在发票等场景中使用?? 1234.56显示为:壹仟贰佰叁拾肆元伍角陆分,那就往下看看吧! 本程序可以实现 0 到 9999 9999 9999.994 以内的人民币大写转换,精确到 ...
- Git 的优点
1. 快速 如果你每移动一下鼠标都要等待五秒,是不是很受不了?版本控制也是一样的,每一个命令多那么几秒钟,一天下来也会浪费你不少时间.Git的操作非常快速,你可以把时间用在别的更有意义的地方. 2. ...
- MVC4中EasyUI Tree异步加载JSON数据生成树
1,首先构造tree接受的格式化数据结构MODEL /// <summary> /// 定义EasyUI树的相关数据,方便控制器生成Json数据进行传递 /// </summar ...
- Git push本地代码到新建远程仓库
快速搞定 1.git init #初始化本地仓库 2.git remote add origin https://git.oschina.net/redArmy/springboot-swagger ...
- STRUCTS 2 UPLOAD
{LJ?Dragon}[标题]structs2 上传文件中文乱码问题 {LJ?Dragon}[Daily] 1.配置struts.xml文件 <?xml version="1.0&qu ...
- UVA 11212 IDA*
移动一块连续的区间使得数列递增.问最少次数. 直接IDA*暴搜,只是我没有想到A*函数,所以就随手写了个连续递增块数作为估价函数,WA了,然后除以2,还是WA,除以3,WA,除以4...过了= = # ...
- Android中的双向链表
1.看源代码必须搞懂Android的数据结构.在init源代码中双向链表listnode使用非常多,它仅仅有prev和next两个指针,没有不论什么数据成员.这个和linux内核的list_head如 ...
- .NET 拼音检索
微软提供了一个Visual Studio International Pack 组件,可以转换简繁体,或者将汉字转换为拼音以及其他语言的支持. https://www.microsoft.com/zh ...
- Unicode 与多字节编码
int _tmain(int argc, _TCHAR* argv[]) { //定义LPWSTR 类型的宽字符串 LPWSTR szUnicode = L"This is a Unicod ...