bzoj2754
看到这道题一开始想到的是后缀数组+二分+rmq
类似bzoj3172
问每个串i在合并后的串出现了多少次
等价于有多少个后缀j,使得LCP(i,j)>=length(s[i])
但是想想又不对,要求求的是有多少人被点到,每个人点到多少次
可能有多个后缀j满足条件但其实都是一个人的名字的一部分
好像二分搞不动,只能顺着名次依次找,理论上极其极端的数据是可以卡掉
但是实际却过了,,内疚啊……
UPD:太神了,这题有非暴力的做法,orz http://oi.nks.edu.cn/showmessage?message_id=4091
const inf=;
var s,sum,be,h,x,y,rank,sa:array[..] of longint;
q,len,w:array[..] of longint;
v:array[..] of boolean;
tot,c,p,m,n,t,l,i,j:longint; function min(a,b:longint):longint;
begin
if a>b then exit(b) else exit(a);
end; procedure suffix(n:longint);
var m:longint;
begin
for i:= to t do
inc(sum[s[i]]);
m:=inf;
for i:= to m do
inc(sum[i],sum[i-]);
for i:=n downto do
begin
sa[sum[s[i]]]:=i;
dec(sum[s[i]]);
end;
p:=;
rank[sa[]]:=;
for i:= to n do
begin
if (s[sa[i]]<>s[sa[i-]]) then inc(p);
rank[sa[i]]:=p;
end;
m:=p;
j:=;
while m<n do
begin
fillchar(sum,sizeof(sum),);
y:=rank;
p:=;
for i:=n-j+ to n do
begin
inc(p);
x[p]:=i;
end;
for i:= to n do
if sa[i]>j then
begin
inc(p);
x[p]:=sa[i]-j;
end; for i:= to n do
begin
rank[i]:=y[x[i]];
inc(sum[rank[i]]);
end;
for i:= to m do
inc(sum[i],sum[i-]);
for i:=n downto do
begin
sa[sum[rank[i]]]:=x[i];
dec(sum[rank[i]]);
end;
p:=;
rank[sa[]]:=;
for i:= to n do
begin
if (y[sa[i]]<>y[sa[i-]]) or (y[sa[i]+j]<>y[sa[i-]+j]) then inc(p);
rank[sa[i]]:=p;
end;
m:=p;
j:=j shl ;
end;
h[]:=;
p:=;
for i:= to n do
begin
if rank[i]= then continue;
j:=sa[rank[i]-];
while s[i+p]=s[j+p] do inc(p);
h[rank[i]]:=p;
if p> then dec(p);
end;
end; begin
readln(n,m);
for i:= to n do
begin
read(l);
for j:= to l do
begin
inc(t);
read(s[t]);
be[t]:=i;
end;
inc(t);
s[t]:=inf; //注意姓和名之间也要加分隔符,防止点名串一部分在姓,一部分在名的情况
read(l);
for j:= to l do
begin
inc(t);
read(s[t]);
be[t]:=i;
end;
inc(t);
s[t]:=inf;
end;
for i:= to m do
begin
read(len[i]);
w[i]:=t+;
for j:= to len[i] do
begin
inc(t);
read(s[t]);
be[t]:=i+n;
end;
inc(t);
s[t]:=inf;
end;
suffix(t);
fillchar(sum,sizeof(sum),);
tot:=;
for i:= to m do
begin
for j:= to tot do //小小优化
v[q[j]]:=false;
tot:=;
j:=rank[w[i]];
l:=;
while j<=t do //找名次比点名串大的后缀
begin
inc(j);
c:=sa[j];
l:=min(h[j],l); //height数组和LCP的关系
if l<len[i] then break
else begin
if (be[c]>=) and (be[c]<=n) and not v[be[c]] then
begin
v[be[c]]:=true; //不能重复统计
inc(tot);
q[tot]:=be[c];
inc(sum[be[c]]);
end;
end;
end;
j:=rank[w[i]];
l:=h[j];
while j> do //找名次比点名串小的后缀
begin
dec(j);
c:=sa[j];
if l<len[i] then break
else begin
if (be[c]>=) and (be[c]<=n) and not v[be[c]] then
begin
v[be[c]]:=true;
inc(tot);
q[tot]:=be[c];
inc(sum[be[c]]);
end;
end;
l:=min(l,h[j]);
end;
writeln(tot);
end;
for i:= to n do
begin
write(sum[i]);
if i<>n then write(' ');
end;
writeln;
end.
bzoj2754的更多相关文章
- 【BZOJ2754】喵星球上的点名(AC自动机)
[BZOJ2754]喵星球上的点名(AC自动机) 题面 BZOJ 题解 友情提示:此题请不要在cogs上提交,它的数据有毒 对于点名串构建\(AC\)自动机 然后把名字丢进去进行匹配, 大力统计一下答 ...
- 【bzoj2754】 SCOI2012—喵星球上的点名
http://www.lydsy.com/JudgeOnline/problem.php?id=2754 (题目链接) 题意 给出$n$个名字串,$m$个点名串,问对于每一个姓名串,它包含多少个点名串 ...
- 【bzoj2754】【scoi2012】喵星球上的点名
题解们: 1.首先可以被很多暴力给搞过去:我以前也是这样水过去的 2.ac自动机 2.1 抽离fail树 对点名建自动机,建$fail$树的时候只保留询问节点: 对于一个喵,子串==在自动机里匹配到的 ...
- 【BZOJ2754】[SCOI2012]喵星球上的点名
[BZOJ2754][SCOI2012]喵星球上的点名 题面 bzoj 洛谷 题解 这题有各种神仙做法啊,什么暴力\(AC\)自动机.\(SAM\)等等五花八门 我这个蒟蒻在这里提供一种复杂度正确且常 ...
- [BZOJ2754] [SCOI2012]喵星球上的点名解题报告|后缀数组
a180285幸运地被选做了地球到喵星球的留学生.他发现喵星人在上课前的点名现象非常有趣. 假设课堂上有N个喵星人,每个喵星人的名字由姓和名构成.喵星球上的老师会选择M个串来点名,每次读出一个串的 ...
- BZOJ2754: [SCOI2012]喵星球上的点名
2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 680 Solved: 314[Submit][Sta ...
- BZOJ2754 SCOI2012喵星球上的点名
绝世好题. 正当我犹豫不决时,hzwer说:“MAP!!!” 没错这题大大的暴力,生猛的stl,贼基尔爽,,ԾㅂԾ,, 由于我们求点名在名字中的子串个数,所以将点名建AC自动机,记录节点属于哪次点名, ...
- BZOJ2754 [SCOI2012]喵星球上的点名 SA+莫队+树状数组
题面 戳这里 题解 首先先把所有给出的姓名和询问全部接在一起,建出\(height\)数组. 某个串要包含整个询问串,其实就相当于某个串与询问串的\(lcp\)为询问串的长度. 而两个后缀\(Suff ...
- bzoj2754:[SCOI2012]喵星球上的点名(后缀自动机)
Description a180285幸运地被选做了地球到喵星球的留学生.他发现喵星人在上课前的点名现象非常有趣. 假设课堂上有N个喵星人,每个喵星人的名字由姓和名构成.喵星球上的老师会选择M个串 ...
随机推荐
- Oracle hextoraw和rawtohex
Oracle hextoraw和rawtohex [日期:2012-07-17] 来源:Linux社区 作者:adrain_001 [字体:大 中 小] HEXTORAW 语法: HEXT ...
- AVAudioSession 的 AVAudioSessionCategory 和 AVAudioSessionCategoryOptions 相关
AVAudioSessionCategory相关 AVAudioSessionCategoryAmbient 使用这个category的应用会随着静音键和屏幕关闭而静音.并且不会中止其它应用播放声音, ...
- Cogs 1298.通讯问题
1298.通讯问题 ★ 输入文件:jdltt.in 输出文件:jdltt.out 简单对比 时间限制:1 s 内存限制:128 MB [题目描述] 一个篮球队有n个篮球队员,每个队员都有联系方式(如电 ...
- unsigned int 转 RGB
unsigned int颜色存储格式:0xaabbggrr,其中a,b,g,r分别表示,透明度.蓝色.绿色.红色. 方法一:使用windows宏 unsigned int clr = 0x00FF00 ...
- Qt 操作Excel
Qt对Excel的数据读/写操作没有现存的类,需要使用QAxObject,下面是从网上下载下来的一个封装好的类,感觉还可以,一般情况下够用,拿来给大家分享. 头文件: #ifndef EXCELENG ...
- spark - 从HDFS加载文件并分析
scala> val file=sc.textFile("/workspace/bpUserinfo_logs/bpUserinfo_20160212.log") scala ...
- foreach的一点理解
首先什么样的数据才能实现foreach 1 实现IEnumerable这个接口 2 有GetEnumerable()这个方法 然后为啥实现这个接口或者有这个方法就可以实现foreach遍历 首先我先用 ...
- tq --uboot使用
- Nand Flash命令- nand info nand erase nand read[.jffs2] addr off size .jffs代表ECC方式不同 nan ...
- View和ViewGroup的区别 -- Touch事件处理
View.java源码: /frameworks/base/core/java/android/view/View.java View.java的 dispatchTouchEvent 方法: 经过一 ...
- python数据库操作之pymysql模块和sqlalchemy模块(项目必备)
pymysql pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同. 1.下载安装 pip3 install pymysql 2.操作数据库 (1).执行sql #! ...