【题目背景】:
zm 喜欢上了吃包子。
【题面描述】:
zm 每天都要去买包子,但是为了减肥,zm 设置了一系列规则来控制他每天买包子的数量。
他随机了 n 个特殊字符串,然后用 n 个字符串来衡量接下来 Q 天每天该买多少个包子。
规则如下:
1.每天 zm 会生成两个字符串,他把一串称为 A 串,另一串称为 B 串。
2. 此时每个特殊字符串有一个值 F[i],当 A 串为第 i 个特殊字符串的前缀且 B 串为第i 个字符串的后缀时(可重叠),F[i]=1,否则 F[i]=0。
3.如果 F[i]当前等于 1,那么说明 zm 要买这个包子。zm 每天晚上会做一个梦,梦里会出现一个数字 K,zm 觉得这个数字不吉利,就想把他买的编号第 K 小的包子给 zackzh,于是 zm 就想知道这个包子的编号。zm 觉得这个问题对他来说太简单了,于是找到了你,让你代他写一个程序解决这个问题。
【输入格式】:
输入到文件 zmchibaozi.in。
第一行包含两个数 n,Q。接下来 n 行,每一行表示一个特殊字符串。接下来 Q 行,每一行表示这一天 zm 生成的 A 串,B 串和 K。
【输出格式】:
输出到文件 zmchibaozi.out。共 Q 行,每一行表示这一天 zm 买的编号第 K 小的包子,若无解则输出-1。
【样例输入】:
3 6
aaaaa
abacabaa
avtobus
a a 1
a aa 2
aa a 2
aaaaa aaaa 1
abac caba 3
abac a 1
【样例输出】:
1
2
-1
1
-1
2
【数据范围】:
用 s1 表示特殊字符串总长度,s2 表示 A 串总长度,s3 表示 B 串总长度。
对于 10%的数据,s1,s2,s3<=5000。
有另外 10%的数据,所有的 A 串一样。
有另外 10%的数据,所有的 B 串一样。
有另外 30%的数据,每个 A 串和 B 串的长度均小于 20 且 n<=10000。
对于 100%的数据,s1<=1000000,s2,s3<=2000000,K<=n,m<=100000,所有字符串都小写。
【题目解析】
首先可以将所有特殊字符串按正反建两颗trie树,这样之后每次询问时找到A,B串在这两颗trie上的节点位置,那么答案就是这两个节点的子树中共有的节点编号第K大的节点。
可以继续抽象模型。
一个节点在这个子树内就是它的dfn在根的dfn和dfn+siz-1之间。
那么可以得到这样一个问题
图中x表示正trie的dfn,y表示反trie的dfn。
将每个特殊串变为一个点(正向trie的dfn,反向trie的dfn)。
将每个询问两个子树中共有点的第K大转化为求矩形中第K大的点。
问题便转化为经典的整体二分。
使用扫描线求解。
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+;
int n,q,size,ans[N],ge,cnt1,cnt2,sh[N],dq[N],dui[N],cj,cc[N];
struct ztef
{
int x1,x2,y1,y2,k,id;
}a[N<<],huan2[N];
struct cha
{
int qi,ho;
}b[N],huan[N];
struct line
{
int he,ze1,ze2,pu,du;
}li[N<<];
string s,ss;
struct pigu
{
int er[N][],dfn[N],cnt,siz[N];
inline int insert(string x)
{
int len=x.size(),now=;
for(int i=;i<len;i++)
{
if(!er[now][x[i]-'a']) er[now][x[i]-'a']=++cnt;
now=er[now][x[i]-'a'];
}
return now;
}
inline void dfs(int now)
{
dfn[now]=++size;siz[now]=;
for(int i=;i<=;i++)
{
if(!er[now][i]) continue;
dfs(er[now][i]);
siz[now]+=siz[er[now][i]];
}
}
inline int cha(string x)
{
int now=,len=x.size();
for(int i=;i<len;i++)
{
if(!er[now][x[i]-'a']) return ;
now=er[now][x[i]-'a'];
}
return now;
}
}zh,fa;
inline int read()
{
char c=getchar();
int x=,f=;
while(!isdigit(c)) {if(c=='-') f=-;c=getchar();}
while(isdigit(c)) {x=(x<<)+(x<<)+c-'';c=getchar();}
return x*f;
}
inline int lowbit(int x)
{
return x&(-x);
}
inline void update(int now,int v)
{
while(now<=cj)
{
sh[now]+=v;
now+=lowbit(now);
}
}
inline int query(int now)
{
int daan=;
if(now<=) return ;
while(now)
{
daan+=sh[now];
now-=lowbit(now);
}
return daan;
}
inline bool cmp2(line x,line y)
{
return x.he<y.he;
}
inline bool cmp1(cha x,cha y)
{
return x.qi<y.qi;
}
inline void solve(int l,int r,int L,int R)
{
if(L>R) return;
if(l==r)
{
if(r==n+) for(int i=L;i<=R;i++) ans[dui[i]]=-;
else for(int i=L;i<=R;i++) ans[dui[i]]=l;
return;
}
int cn3=,mid=(l+r)>>,cn1=,cn2=;
for(int i=l;i<=mid;i++)
huan[++cn1]=b[i];
sort(huan+,huan+cn1+,cmp1);
for(int i=L;i<=R;i++)
{
if(ans[dui[i]]==-) continue;
li[++cn2]=(line){a[dui[i]].x1-,a[dui[i]].y1,a[dui[i]].y2,-,i};
li[++cn2]=(line){a[dui[i]].x2,a[dui[i]].y1,a[dui[i]].y2,,i};
}
sort(li+,li+cn2+,cmp2);
for(int i=;i<=cn2;i++)
{
while(cn3<=cn1&&huan[cn3].qi<=li[i].he)
{
update(huan[cn3].ho,);
cn3++;
}
dq[li[i].du]+=(query(li[i].ze2)-query(li[i].ze1-))*li[i].pu;
}
for(int i=;i<cn3;i++)
update(huan[i].ho,-);
int hu1=L,hu2=R;
for(int i=L;i<=R;i++)
{
if(dq[i]>=a[dui[i]].k)
cc[hu1++]=dui[i];
else
{
cc[hu2--]=dui[i];
a[dui[i]].k-=dq[i];
}
dq[i]=;
}
for(int i=L;i<=R;i++) dui[i]=cc[i];
solve(l,mid,L,hu1-);
solve(mid+,r,hu2+,R);
}
int main()
{
n=read();q=read();
for(int i=;i<=n;i++)
{
cin>>s;
b[i].qi=zh.insert(s);
reverse(s.begin(),s.end());
b[i].ho=fa.insert(s);
}
zh.dfs();size=;fa.dfs();
for(int i=;i<=n;i++)
{
b[i].qi=zh.dfn[b[i].qi];
b[i].ho=fa.dfn[b[i].ho];
}
cj=fa.cnt+;
for(int i=,x,y,z;i<=q;i++)
{
cin>>s>>ss>>z;
dui[i]=i;
reverse(ss.begin(),ss.end());
x=zh.cha(s);
y=fa.cha(ss);a[i].k=z;
if(x==||y==) {ans[i]=-;continue;}
a[i].id=i;
a[i].x1=zh.dfn[x];a[i].x2=zh.dfn[x]+zh.siz[x]-;
a[i].y1=fa.dfn[y];a[i].y2=fa.dfn[y]+fa.siz[y]-;
}
solve(,n+,,q);
for(int i=;i<=q;i++) cout<<ans[i]<<"\n";
return ;
}

zm吃包子的更多相关文章

  1. 嘉馨学姐又双叒叕来吃包子了 QDUOJ 模拟 尺度法

    嘉馨学姐又双叒叕来吃包子了 QDUOJ 模拟 尺度法 点我进入OJ题目详情 题意 给你一串数,让你求长度最长的子串,这个字串满足里面没有重复出现的数字. 解题思路 使用一个标记数组,来标记每个数的第一 ...

  2. Java实现 蓝桥杯 算法训练 猴子吃包子(暴力)

    试题 算法训练 猴子吃包子 问题描述 从前,有一只吃包子很厉害的猴子,它可以吃无数个包子,但是,它吃不同的包子速度也不同:肉包每秒钟吃x个:韭菜包每秒钟吃y个:没有馅的包子每秒钟吃z个:现在有x1个肉 ...

  3. 初识python: 生成器并行(做包子,吃包子)

    知识点: send(i) :唤醒yield,并将 i 的值传给 yield #!/user/bin env python # author:Simple-Sir # time:20181020 # 单 ...

  4. 等待唤醒机制代码实现_包子类&包子铺类和等待唤醒机制代码实现_吃货类&测试类

    资源类:包子类 设置包子的属性 皮 陷 包子的状态:有 true 没有 false public class BaoZi { //皮 String pi; //陷 String xian; //包子的 ...

  5. Python高手之路【四】python函数装饰器

    def outer(func): def inner(): print('hello') print('hello') print('hello') r = func() print('end') p ...

  6. celery 框架

    转自:http://www.cnblogs.com/forward-wang/p/5970806.html 生产者消费者模式 在实际的软件开发过程中,经常会碰到如下场景:某个模块负责产生数据,这些数据 ...

  7. python学习之路 第四天

    1.函数动态参数: #!/usr/bin/env python3     def show(*sss,**eee):         print(sss,type(sss))         prin ...

  8. Day5-python基础之函数(二)

    生成器 迭代器 装饰器 模块   来个需求,一个列表中所有元素都+1 1.最容易想到的方法 for循环,找列表索引,对应每个值+1 list_old = [1,2,3,4,5,6,7,8,9] for ...

  9. Python之路,Day5 - Python基础5

    本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 一.列表生成器 , 1, 2, 3, 4, 5, 6, 7, 8, 9 ...

随机推荐

  1. Laravel5.3使用学习笔记---中间件

    Laravel提供了中间件的使用.那什么是中间件呢,根据用法,我总结为,夹在“请求—>控制器—>响应—>end”中间运行的代码片段.本文将以官方英文文本为基础资料进行笔记记录. La ...

  2. tsung测试xmpp遇到no_free_userid

    tsung里面可以配置xmpp的参数,设置一下 <option type="ts_jabber" name="userid_max" value=&quo ...

  3. 【t002】jam的计数法

    Time Limit: 1 second Memory Limit: 50 MB [问题描述] Jam是个喜欢标新立异的科学怪人.他不使用阿拉伯数字计数,而是使用小写英文字母计数,他觉得这样做,会使世 ...

  4. UVa 1635 - Irrelevant Elements-[分解质因数]

    Young cryptoanalyst Georgie is investigating different schemes of generating random integer numbers ...

  5. vue-上传文件

    <label for="exampleInputFile">头像</label> <img :src=" imgsrc != '' ? im ...

  6. tensorflow在文本处理中的使用——skip-gram & CBOW原理总结

    摘自:http://www.cnblogs.com/pinard/p/7160330.html 先看下列三篇,再理解此篇会更容易些(个人意见) skip-gram,CBOW,Word2Vec 词向量基 ...

  7. vscode 添加golang插件

    安装好git 下列命令中的路径一定要按照自己实际的路径来 mkdir -p $GOPATH/src/golang.org/x  //路径下创建此文件cd $GOPATH/src/golang.org/ ...

  8. oracle 查询含clob 字段慢

    项目中使用Oracle 查询表数据感觉特别慢,一秒只能查询十条记录. 刚开始以为是全表扫描的问题,加上索引 生效后,查询还是很慢. 表中只有三个字段,其中一个是clob,于是推测,是不是查询字段的原因 ...

  9. web应用中web.xml文件的解释

    一.web.xml配置文件常用元素及其意义预览 1 <web-app> 2 3 <!--定义了WEB应用的名字--> 4 <display-name></di ...

  10. umask 设置

    背景: 有时候需要在linux上从其他人的目录里copy文件过来. 最近遇上的事情很麻烦,就是copy的时候发现很多文件copy不过来,copy一个文件夹时,当前文件把权限修改了,结果子目录的中的还没 ...