P3587 [POI2015]POD
题目描述
长度为n的一串项链,每颗珠子是k种颜色之一。 第i颗与第i-1,i+1颗珠子相邻,第n颗与第1颗也相邻。切两刀,把项链断成两条链。要求每种颜色的珠子只能出现在其中一条链中。求方案数量(保证至少存在一种),以及切成的两段长度之差绝对值的最小值。
输入输出格式
输入格式:
第一行n,k(2<=k<=n<=1000000)。颜色从1到k标号。接下来n个数,按顺序表示每颗珠子的颜色。(保证k种颜色各出现至少一次)。
输出格式:
一行两个整数:方案数量,和长度差的最小值
输入输出样例
9 5
2 5 3 2 2 4 1 1 3
4 3
说明
长度为n的一串项链,每颗珠子是k种颜色之一。 第i颗与第i-1,i+1颗珠子相邻,第n颗与第1颗也相邻。
切两刀,把项链断成两条链。要求每种颜色的珠子只能出现在其中一条链中。
求方案数量(保证至少存在一种),以及切成的两段长度之差绝对值的最小值。
Solution:
本题思维题,ZYYS。
还记得前面HRZ学长讲的一道判断相似字符串的题目(那题做法是处理出26个字母分别为关键字的01hash值,排序后判断相等),本题做法类似,先将原数列的断点按每种颜色的出现次数求环形前缀和,因为是环形,所以最后一个该颜色的后面的断点前缀和为0,我们以样例为例:
留图带画(手绘勿喷)。
不难发现能切两刀的位置所对应的$k$元组一定相等,证明很简单:若这两个位置对应的$k$元组相等,那么同一颜色的环形前缀和是相等的,这就说明在这两位置切出的两段中有一段一定不包含该颜色,于是另一段一定包含所有的该颜色咯。
那么我们将每个位置的$k$元组处理出来,由于$k\leq 10^6$又要比较相等,所以还得hash。
于是第一问就迎刃而解了,只需要对hash值排序,然后组合计数。
第二问要求分出的两段的差的最小值,设断点为$l,r$,那么差值$=|n-2*(r-l)|$(注意$(r-l)$不用+1,因为l、r为断点标号,之间有r-l个颜色),显然要使的差值最小,就得使$r-l$尽可能接近$n/2$,满足单调性,于是直接单调队列,实现时在第一问的过程中对于hash值相等的一段处理并更新答案就好了。
(坑点:卡单hash,所以得双hash,然后$k$很大,所以基数也得选大,分别选两组孪生素数就OK啦!>.^_^.<)
代码:
/*Code by 520 -- 9.3*/
#include<bits/stdc++.h>
#define il inline
#define ll long long
#define RE register
#define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
using namespace std;
const int N=,P1=,P2=,mod1=1e9+,mod2=1e9+;
ll s1[N],s2[N],h1[N],h2[N];
int n,k,a[N],b[N],c[N];
struct node{
int id;
ll sum1,sum2;
bool operator <(const node &a)const {
if(sum1!=a.sum1)return sum1<a.sum1;
if(sum2!=a.sum2)return sum2<a.sum2;
return id<a.id;
}
}t[N]; int gi(){
int a=;char x=getchar();
while(x<''||x>'')x=getchar();
while(x>=''&&x<='')a=(a<<)+(a<<)+(x^),x=getchar();
return a;
} int main(){
n=gi(),k=gi();
For(i,,n) a[i]=gi();
s1[]=s2[]=;
For(i,,k) s1[i]=s1[i-]*P1%mod1,s2[i]=s2[i-]*P2%mod2;
Bor(i,,n) if(!b[a[i]]) b[a[i]]=i;
ll sum1=,sum2=;
For(i,,n) {
c[a[i]]++;
sum1=(sum1+s1[a[i]])%mod1,sum2=(sum2+s2[a[i]])%mod2;
if(b[a[i]]==i)
sum1=(sum1-s1[a[i]]*c[a[i]]%mod1+mod1)%mod1,
sum2=(sum2-s2[a[i]]*c[a[i]]%mod2+mod2)%mod2;
t[i]=node{i,sum1,sum2};
}
sort(t+,t+n+);
int mid=n+>>,ans=n;
ll cnt=;
for(RE int i=;i<=n;){
RE int nxt=i;
while(nxt<=n&&t[nxt].sum1==t[i].sum1&&t[nxt].sum2==t[i].sum2) nxt++;
cnt+=1ll*(nxt-i)*(nxt-i-)/;
for(int l=i,r=i;r<nxt;r++){
while(l<r&&t[r].id-t[l].id>=mid)l++;
int tp1=abs(n-*(t[r].id-t[l].id));
if(l>i){
int tp2=abs(n-*(t[r].id-t[l-].id));
if(tp2<tp1)tp1=tp2;
}
if(tp1<ans)ans=tp1;
}
i=nxt;
}
printf("%lld %d\n",cnt,ans);
return ;
}
P3587 [POI2015]POD的更多相关文章
- Luogu3587[POI2015]POD - hash + 单调队列
Solution 还是去看了题解. 感谢大佬的博客→ 题解传送门 是一道思路比较新的题. 搞一个前缀和, 记录前 $i$ 个位置每种颜色的出现次数, 如果位置 $i$ 是 颜色 $a[i]$ 的最后 ...
- POI2015 解题报告
由于博主没有BZOJ权限号, 是在洛咕做的题~ 完成了13题(虽然有一半难题都是看题解的QAQ)剩下的题咕咕咕~~ Luogu3585 [POI2015]PIE Solution 模拟, 按顺序搜索, ...
- pod Spec管理配置
pod Spec 为自己的项目添加pod管理功能.前言: 上一篇文章中提到,因为自己在操作的时候遇到很多坑,所在在此做一个记录,同样也希望可以帮到在这个操作上遇到坑的人. 本文将采用配图和加文字的方式 ...
- iOS pod install update 慢!!!
在终端输入: pod install --verbose --no-repo-update pod update --verbose --no-repo-update
- 使用 pod install 还是 pod update ?
翻译自:https://guides.cocoapods.org/using/pod-install-vs-update.html 介绍: 许多人开始使用CocodPods的时候认为pod insta ...
- CocoaPods pod install
加参数可以提升更新的速度 方法1: pod install --verbose --no-repo-update pod update --verbose --no-repo-update 方法2: ...
- CocoaPods pod 安装、更新慢解决方法
使用CocoaPods来添加第三方类库,无论是执行pod install还是pod update都卡在了Analyzing dependencies不动了,令人甚是DT. 每一次都忘记现在自己记录一下 ...
- pod的SDK报错,Linker command failed with exit code1(use -v to see invocation)
错误1789个重复的符号: 原因是我用cocopads 导入了重复的SDK 环信的SDK EaseMobSDK: 不包含语音的 EaseMobSDKFull: 包含语音的 在Podfile中将导入E ...
- 使用私有Pod Spec的类库--提高公司开发效率
前言 找了这么长时间,再次开始去尝试Cocoapods了.前面已经写过一篇关于如何把自己的Github上的代码库添加Cocoapods支持.现在就让我们看一下如果搭建私有的Spec吧. 之所以构建私有 ...
随机推荐
- SAP 费用
SAP在华真相:天价收费与用户之灾 SAP真的是企业实施ERP系统的最佳选择吗? 画皮SAP-世界管理软件公司的中国真相 你知道SAP吗?哦,知道,满大街都是嘛,S-P-A,SPA.做出上述回答的是一 ...
- mysql攻防之写入漏洞
因为被别人利用mysql攻击,所以想在这里帮助大家提高一下自身mysql的安全.避免成为别人的肉鸡. show global variables like '%secure%'; 如果是这样则黑客可以 ...
- html5新增标签做基本布局
结构标记 ***** 做布局 1.<header>元素 <header></header> ==> <div id="header" ...
- because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled
spring security 配置问题,静态资源未被允许访问
- oracle 的查询问题!!!
问题: declare aaa integer;email varchar2(100) :='1234@aa.com';begin select count(*) into aaa from dual ...
- 全国高校绿色计算大赛 预赛第一阶段(C++)第4关:计算日期
挑战任务 我们吃的食物都有保质期,现在食品监督管理局想要制作一个能准确计算食品过期日期的小程序,需要请你来进行设计. 例如:A食品在2018年1月1日生产,保质期是20天,则它的过期日期在2018年1 ...
- vim常用命令之多行注释和多行删除
vim中多行注释和多行删除命令,这些命令也是经常用到的一些小技巧,可以大大提高工作效率. 1.多行注释: 1. 首先按esc进入命令行模式下,按下Ctrl + v,进入列(也叫区块)模式; ...
- MongoDB修改默认数据库
在某些情况下,我们并不想把mongoDB的数据库放在c盘,这时候有两种方法可以切换数据库目录. 1.命令方式 首先创建数据路目录,例如:E:\data\db.然后运行命令 mongod -dbpath ...
- random 模块 时间模块(time) sys模块 os模块
random 模块 1.随机小数 random.random() 0-1内的随机小数 random.uniform(1,5) 1-5范围内的随机小数 2.随机整数 random.randint( ...
- [剑指Offer]47-礼物的最大价值(DP)
题目描述 在一个m*n的棋盘每个格有一个礼物,每个礼物有一定价值(>0).从棋盘左上角到右下角,只能向下或向右走,问能拿到的礼物最大价值. 解题思路 dp. 可将二维数组版优化为一维数组版. 代 ...