【BZOJ4199&UOJ131】品酒大会(后缀数组,并查集)
题意:
两杯“r相似” (r>1)的酒同时也是“1 相似”、“2 相似”、……、“(r−1) 相似”的。
n<=300000 abs(a[i])<=10^9
思路:对于i,j两个后缀,它们的贡献只与它们的lcp有关
而lcp又是它们之间height的最小值
所以可以把height从大到小排序
然后用并查集合并最值,方案数之类的
每次合并的都是排名相邻的一对后缀,相当于一段不相交的线段
每个集合中的lcp即为height的最小值
将r相似的加到r-1相似中
被UOJ的extra卡了一发,原来是0相似的初始最大值忘记初始化了
- const oo=<<;
- var sum,f:array[..]of int64;
- sa,rank,height,id,mx,mn,size,a,fa,x,y,wc,wd,b:array[..]of longint;
- n,m,i,p,q,t:longint;
- ch:ansistring;
- procedure swap(var x,y:longint);
- var t:longint;
- begin
- t:=x; x:=y; y:=t;
- end;
- function max(x,y:int64):int64;
- begin
- if x>y then exit(x);
- exit(y);
- end;
- function min(x,y:longint):longint;
- begin
- if x<y then exit(x);
- exit(y);
- end;
- procedure qsort(l,r:longint);
- var i,j,mid:longint;
- begin
- i:=l; j:=r; mid:=height[id[(l+r)>>]];
- repeat
- while mid<height[id[i]] do inc(i);
- while mid>height[id[j]] do dec(j);
- if i<=j then
- begin
- swap(id[i],id[j]);
- inc(i); dec(j);
- end;
- until i>j;
- if l<j then qsort(l,j);
- if i<r then qsort(i,r);
- end;
- function find(k:longint):longint;
- begin
- if fa[k]<>k then fa[k]:=find(fa[k]);
- find:=fa[k];
- end;
- procedure merge(x,y:longint);
- begin
- size[y]:=size[y]+size[x];
- mx[y]:=max(mx[x],mx[y]);
- mn[y]:=min(mn[x],mn[y]);
- fa[x]:=y;
- end;
- function cmp(a,b,l:longint):boolean;
- begin
- exit((y[a]=y[b])and(y[a+l]=y[b+l]));
- end;
- procedure getsa(n:longint);
- var i,j,p:longint;
- begin
- for i:= to n- do
- begin
- x[i]:=a[i];
- inc(wc[a[i]]);
- end;
- for i:= to m- do wc[i]:=wc[i-]+wc[i];
- for i:=n- downto do
- begin
- dec(wc[x[i]]);
- sa[wc[x[i]]]:=i;
- end;
- j:=; p:=;
- while p<n do
- begin
- p:=;
- for i:=n-j to n- do
- begin
- y[p]:=i; inc(p);
- end;
- for i:= to n- do
- if sa[i]>=j then begin y[p]:=sa[i]-j; inc(p); end;
- for i:= to n- do wd[i]:=x[y[i]];
- for i:= to m- do wc[i]:=;
- for i:= to n- do inc(wc[wd[i]]);
- for i:= to m- do wc[i]:=wc[i-]+wc[i];
- for i:=n- downto do
- begin
- dec(wc[wd[i]]);
- sa[wc[wd[i]]]:=y[i];
- end;
- for i:= to n do swap(x[i],y[i]);
- p:=; x[sa[]]:=;
- for i:= to n- do
- if cmp(sa[i-],sa[i],j) then x[sa[i]]:=p-
- else
- begin
- x[sa[i]]:=p; inc(p);
- end;
- j:=j*;
- m:=p;
- end;
- end;
- procedure getheight(n:longint);
- var i,j,k:longint;
- begin
- for i:= to n do rank[sa[i]]:=i;
- k:=;
- for i:= to n- do
- begin
- if k> then dec(k);
- j:=sa[rank[i]-];
- while a[i+k]=a[j+k] do inc(k);
- height[rank[i]]:=k;
- end;
- end;
- begin
- assign(input,'bzoj4199.in'); reset(input);
- assign(output,'bzoj4199.out'); rewrite(output);
- readln(n);
- readln(ch);
- for i:= to n- do a[i]:=ord(ch[i+])-ord('a')+;
- a[n]:=; m:=;
- getsa(n+);
- getheight(n);
- for i:= to n- do read(b[i]);
- for i:= to n do
- begin
- fa[i]:=i;
- size[i]:=; mx[i]:=b[sa[i]]; mn[i]:=mx[i];
- f[i]:=-oo;
- end;
- f[]:=-oo;
- for i:= to n- do id[i]:=i+;
- qsort(,n-);
- for i:= to n- do
- begin
- p:=find(id[i]-); q:=find(id[i]);
- t:=height[id[i]];
- sum[t]:=sum[t]+int64(size[p])*size[q];
- f[t]:=max(f[t],int64(mx[p])*mx[q]);
- f[t]:=max(f[t],int64(mx[p])*mn[q]);
- f[t]:=max(f[t],int64(mn[p])*mx[q]);
- f[t]:=max(f[t],int64(mn[p])*mn[q]);
- merge(p,q);
- end;
- for i:=n- downto do
- begin
- sum[i]:=sum[i]+sum[i+];
- f[i]:=max(f[i],f[i+]);
- end;
- for i:= to n- do
- if f[i]>-oo then writeln(sum[i],' ',f[i])
- else writeln(,' ',);
- close(input);
- close(output);
- end.
【BZOJ4199&UOJ131】品酒大会(后缀数组,并查集)的更多相关文章
- [UOJ#131][BZOJ4199][NOI2015]品酒大会 后缀数组 + 并查集
[UOJ#131][BZOJ4199][NOI2015]品酒大会 试题描述 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个 ...
- NOI 2015 品酒大会 (后缀数组+并查集)
题目大意:略 40分暴力还是很好写的,差分再跑个后缀和 和 后缀最大值就行了 一种正解是后缀数组+并查集 但据说还有后缀数组+单调栈的高端操作蒟蒻的我当然不会 后缀数组求出height,然后从大到小排 ...
- 【BZOJ-4199】品酒大会 后缀数组 + 并查集合并集合
4199: [Noi2015]品酒大会 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 436 Solved: 243[Submit][Status] ...
- 【BZOJ4199】[Noi2015]品酒大会 后缀数组+并查集
[BZOJ4199][Noi2015]品酒大会 题面:http://www.lydsy.com/JudgeOnline/wttl/thread.php?tid=2144 题解:听说能用SAM?SA默默 ...
- [NOI2015] 品酒大会 - 后缀数组,并查集,STL,启发式合并
[NOI2015] 品酒大会 Description 对于每一个 \(i \in [0,n)\) 求有多少对后缀满足 LCP 长度 \(\le i\) ,并求满足条件的两个后缀权值乘积的最大值. So ...
- BZOJ 4199: [Noi2015]品酒大会( 后缀数组 + 并查集 )
求出后缀数组后, 对height排序, 从大到小来处理(r相似必定是0~r-1相似), 并查集维护. 复杂度O(NlogN + Nalpha(N)) ------------------------- ...
- 【学术篇】NOI2015 品酒大会 后缀数组+并查集
省选前大致是刷不了几道题了... 所以就找一些裸一点的题目练练板子算了= = 然而这题一点都不裸, 也并不怎么好写... 于是就浪费了将近一下午的时间... 然而还不是因为后缀数组板子不熟= = 首先 ...
- Uoj #131. 【NOI2015】品酒大会 后缀数组,并查集
#131. [NOI2015]品酒大会 统计 描述 提交 自定义测试 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个奖项, ...
- BZOJ 4566 JZYZOJ 1547 [haoi2016T5]找相同子串 后缀数组 并查集
http://172.20.6.3/Problem_Show.asp?id=1547 http://www.lydsy.com/JudgeOnline/problem.php?id=4566 单纯后缀 ...
- BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]
4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...
随机推荐
- TCP/IP 3握手4挥手
转:摘自<图解TCP/IP>P204 三次握手与四次挥手的状态转移图如下: 如图,由于第二次握手接收端发送SYN+ACK信号所以握手只用了三次,挥手由于接收端ACK和FIN分两次发的,所以 ...
- win7如何设置自动关机
如果想设置Win7按照自己意愿自动关机,而又不希望下载安装第三方软件,则可以通过以下两个方法来简单实现. 工具/原料 Windows7操作系统环境 方法1:利用cmd命令 1 打开cmd窗口. 方法一 ...
- 对比hive和mysql查询汇总
由于底层的处理机制大不相同,hive和mysql在查询上还是有较大差异的! 单个表的select操作 最简单的查询 ,字段2 frome 表名 where 字段 [not]in(元素1,元素2): 例 ...
- Farseer.net轻量级开源框架 入门篇:逻辑层的选择
导航 目 录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 入门篇:增.删.改.查操作演示 下一篇:Farseer.net轻量级开源框架 入门 ...
- linux使用crontab实现PHP执行计划定时任务
linux使用crontab实现PHP执行计划定时任务 前几天写过一篇文章,利用单纯的php实现定时执行任务,但是效率不佳,对于linux来说用crontab实现更加合理 首先说说cron,它是一个l ...
- DeepMind:所谓SACX学习范式
机器人是否能应用于服务最终还是那两条腿值多少钱,而与人交互,能真正地做"服务"工作,还是看那两条胳膊怎么工作.大脑的智能化还是非常遥远的,还是先把感受器和效应器做好才是王道. 关于 ...
- Linux基础之操作系统
一.什么是操作系统 简单来说,操作系统就是一个协调.管理和控制计算机硬件资源和软件资源的控制程序. 二.操作系统存在的意义 究根结底,我们日常对计算机的管理是对计算机硬件的管理.经过近百年的时间,现代 ...
- Java学习4_一些基础4_输入输出_16.5.7
读取输入: 想从控制台进行输入,首先需要构造一个Scanner对象,并与“标准输入流”System.in关联. Scanner in=new Scanner(System.in); String na ...
- Android(java)学习笔记204:JNI之native方法头文件的生成
1. JDK1.6 ,进入到工程的bin目录下classes目录下: 使用命令: javah packageName.ClassName 会在当前目录下生成头文件,从头文件找到jni协议方法 下面举 ...
- Redis系列(七)--Sentinel哨兵模式
在上一篇文章了解了主从复制,主从复制本身的容错性很差,一旦master挂掉,只能进行手动故障转移,很难完美的解决这个问题 而本文讲解的sentinel可以解决这个问题 Redis sentinel示意 ...