BZOJ4382[POI2015] Podział naszyjnika
来源:互联网 发布:弹丸论破未来篇 知乎 编辑:程序博客网 时间:2024/06/14 02:45
BZOJ4382[POI2015] Podział naszyjnika
Description
长度为n的一串项链,每颗珠子是k种颜色之一。 第i颗与第i-1,i+1颗珠子相邻,第n颗与第1颗也相邻。
切两刀,把项链断成两条链。要求每种颜色的珠子只能出现在其中一条链中。
求方案数量(保证至少存在一种),以及切成的两段长度之差绝对值的最小值。
Input
第一行n,k(2<=k<=n<=1000000)。颜色从1到k标号。
接下来n个数,按顺序表示每颗珠子的颜色。(保证k种颜色各出现至少一次)。
Output
一行两个整数:方案数量,和长度差的最小值
Sample Input
9 5
2 5 3 2 2 4 1 1 3
Sample Output
4 3
HINT
四种方法中较短的一条分别是(5),(4),(1,1),(4,1,1)。相差最小值6-3=3。
Solution:
考虑怎么样的情况下可以分割。我们按照前缀给环上可以分割的点进行编号:
可以发现如果前缀相同,此两点之间就可以断开,当然,因为是环形,最后一个该颜色点之后该颜色的点前缀就应编号为0。于是对于每个点都对应一个
这题还卡哈希,用了双哈希才过。
#include<stdio.h>#include<ctype.h>#include<string.h>#include<iostream>#include<algorithm>#define B1 200019#define B2 200011#define M 1000005#define P1 1000000007#define P2 1000000009#define ll long longusing namespace std;struct Node{ int id,res1,res2; bool operator <(const Node &a)const{ if(res1!=a.res1)return res1<a.res1; else if(res2!=a.res2)return res2<a.res2; else return id<a.id; }}Q[M];int A[M],Base1[M],Base2[M],ed[M],cnt[M];void Rd(int &res){ char c;res=0; while(c=getchar(),!isdigit(c)); do{ res=(res<<1)+(res<<3)+(c^48); }while(c=getchar(),isdigit(c));}int main(){ int n,k; Rd(n);Rd(k); for(int i=1;i<=n;i++)Rd(A[i]); Base1[0]=Base2[0]=1; for(int i=1;i<=k;i++){ Base1[i]=(1LL*Base1[i-1]*B1)%P1; Base2[i]=(1LL*Base2[i-1]*B2)%P2; } memset(ed,-1,sizeof(ed)); for(int i=n;i>=1;i--){ if(~ed[A[i]])continue; ed[A[i]]=i; } int res1=0,res2=0; for(int i=1;i<=n;i++){ cnt[A[i]]++; res1=(res1+Base1[A[i]])%P1; res2=(res2+Base2[A[i]])%P2; if(ed[A[i]]==i)res1=((res1-1LL*Base1[A[i]]*cnt[A[i]])%P1+P1)%P1; if(ed[A[i]]==i)res2=((res2-1LL*Base2[A[i]]*cnt[A[i]])%P2+P2)%P2; Q[i].id=i;Q[i].res1=res1;Q[i].res2=res2; } sort(Q+1,Q+n+1); int Half=(n+1)/2,ans=n; ll cnt=0; for(int i=1;i<=n;){ int nxt=i; while(nxt<=n&&Q[nxt].res1==Q[i].res1&&Q[nxt].res2==Q[i].res2)nxt++; cnt+=1LL*(nxt-i)*(nxt-i-1)/2; for(int L=i,R=i;R<nxt;R++){ while(L<R&&Q[R].id-Q[L].id>=Half)L++; int rs1=abs(n-2*(Q[R].id-Q[L].id)); if(L>i){ int rs2=abs(n-2*(Q[R].id-Q[L-1].id)); if(rs2<rs1)rs1=rs2; } if(rs1<ans)ans=rs1; } i=nxt; } cout<<cnt<<' '<<ans<<endl;}
0 0
- BZOJ4382: [POI2015]Podział naszyjnika
- BZOJ4382[POI2015] Podział naszyjnika
- BZOJ4382: [POI2015]Podział naszyjnika
- BZOJ3749[POI2015] Łasuchy
- BZOJ3749 POI2015 Łasuchy
- 3749: [POI2015]Łasuchy
- BZOJ3749: [POI2015]Łasuchy
- BZOJ 3749 [POI2015]Łasuchy
- bzoj 3749: [POI2015]Łasuchy
- BZOJ4385: [POI2015]Wilcze doły
- BZOJ4385: [POI2015]Wilcze doły
- [bzoj4385/POI2015]Wilcze doły
- BZOJ4385[POI2015] Wilcze doły
- BZOJ4385 POI2015 Wilcze doły
- 4385: [POI2015]Wilcze doły
- BZOJ 4385: [POI2015]Wilcze doły
- 【bzoj4385】 [POI2015]Wilcze doły
- 4385: [POI2015]Wilcze doły
- Android集成支付宝踩过的坑
- VS2015给命令行添加参数
- 机器学习之(四)特征工程以及特征选择的工程方法
- multirotor flight control
- Bellman及其优化
- BZOJ4382[POI2015] Podział naszyjnika
- UVA 10559 Blocks(记忆化dp)
- bzoj 4515: [Sdoi2016]游戏(树链剖分+线段树)
- CountDownLatch的介绍和使用
- Dijkstar及其优先队列优化
- HTML5中的save()和restore()方法的用法
- 机器学习之(三)梯度下降法的三种形式BGD、SGD以及MBGD
- CSRF跨域请求伪造
- 理解RESTful架构