【BZOJ4382】[POI2015]Podział naszyjnika 堆+并查集+树状数组
【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
2 5 3 2 2 4 1 1 3
Sample Output
HINT
四种方法中较短的一条分别是(5),(4),(1,1),(4,1,1)。相差最小值6-3=3。
题解:hash那么巧妙的做法我怎么想得到啊~我只会无脑的数据结构。
防止重复,我们不倍长原序列,然后枚举一条切割线r,只考虑另一条切割线l在这条左边的情况。那么对于每种颜色,它只能有一下两种存在方式。
1.2.
对于第一种情况,我们可以对每个点维护上一个与它颜色相同的位置pre,然后只需要满足pre<=l即可。可以用堆维护pre的最大值。
对于第二种情况,我们已经枚举到了这个颜色最右面的点,现在只需要将这个颜色最左端和最右端中间的点全部删除。用并查集维护,并用树状数组统计区间中已经被删除的点的个数即可。
于是方案数量我们很容易就能求出来了。那么长度差的最小值怎么办?我们对于右端点r,肯定是希望找到离r-n/2最近的合法的l。可以用并查集找到每个点左面和右面第一个没被删除的点,判断一下就行。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int maxn=1000010;
typedef long long ll;
int n,m,ans;
ll sum;
int v[maxn],pos[maxn],f[maxn],s[maxn],siz[maxn];
vector<int> p[maxn];
struct heap
{
priority_queue<int> qa,qb;
inline void push(int x) {qa.push(x);}
inline void erase(int x) {qb.push(x);}
inline int top()
{
while(qb.size()&&qa.top()==qb.top()) qa.pop(),qb.pop();
return qa.size()?qa.top():0;
}
}q;
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int find(int x)
{
return (f[x]==x)?x:(f[x]=find(f[x]));
}
inline int abs(int x)
{
return x>0?x:-x;
}
inline void updata(int x)
{
for(int i=x;i<=n;i+=i&-i) s[i]++;
}
inline int query(int x)
{
if(x==-1) return 0;
int i,ret=0;
for(i=x;i;i-=i&-i) ret+=s[i];
return ret;
}
int main()
{
n=rd(),m=rd();
int i,j,k;
for(i=1;i<=n;i++)
{
v[i]=rd(),p[v[i]].push_back(i),pos[i]=p[v[i]].size()-1,f[i]=i,siz[i]=1;
}
f[0]=1,f[n+1]=n+1,siz[n+1]=1;
ans=n;
for(i=1;i<n;i++)
{
if(pos[i]) q.erase(p[v[i]][pos[i]-1]);
if(pos[i]==(int)p[v[i]].size()-1)
{
for(j=find(p[v[i]][0]);j<i;j=f[j]) updata(j),siz[find(j+1)]+=siz[j],f[j]=f[j+1];
}
else q.push(i);
k=q.top();
sum+=i-k-(query(i-1)-query(k-1));
j=find(max(k,i-n/2));
if(j<i) ans=min(ans,abs(n-2*(i-j)));
j-=siz[j];
if(j>=k) ans=min(ans,abs(n-2*(i-j)));
}
printf("%lld %d",sum,ans);
return 0;
}
【BZOJ4382】[POI2015]Podział naszyjnika 堆+并查集+树状数组的更多相关文章
- BZOJ-3211花神游历各国 并查集+树状数组
一开始想写线段树区间开方,简单暴力下,但觉得变成复杂度稍高,懒惰了,编了个复杂度简单的 3211: 花神游历各国 Time Limit: 5 Sec Memory Limit: 128 MB Subm ...
- BZOJ3211 花神游历各国 并查集 树状数组
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3211 题意概括 有n个数形成一个序列. m次操作. 有两种,分别是: 1. 区间开根(取整) 2. ...
- hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点)
hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点) 题意: 给一张无向连通图,有两种操作 1 u v 加一条边(u,v) 2 u v 计算u到v路径上桥的个数 ...
- 【bzoj4869】[Shoi2017]相逢是问候 扩展欧拉定理+并查集+树状数组
题目描述 Informatik verbindet dich und mich. 信息将你我连结. B君希望以维护一个长度为n的数组,这个数组的下标为从1到n的正整数.一共有m个操作,可以分为两种:0 ...
- HDU 5458 Stability(双连通分量+LCA+并查集+树状数组)(2015 ACM/ICPC Asia Regional Shenyang Online)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5458 Problem Description Given an undirected connecte ...
- la4730(并查集+树状数组)
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=30& ...
- 【BZOJ3211】花神游历各国 并查集+树状数组
[BZOJ3211]花神游历各国 Description Input Output 每次x=1时,每行一个整数,表示这次旅行的开心度 Sample Input 41 100 5 551 1 22 1 ...
- HDU 4750 Count The Pairs ★(图+并查集+树状数组)
题意 给定一个无向图(N<=10000, E<=500000),定义f[s,t]表示从s到t经过的每条路径中最长的边的最小值.Q个询问,每个询问一个t,问有多少对(s, t)使得f[s, ...
- Hdu 5458 Stability (LCA + 并查集 + 树状数组 + 缩点)
题目链接: Hdu 5458 Stability 题目描述: 给出一个还有环和重边的图G,对图G有两种操作: 1 u v, 删除u与v之间的一天边 (保证这个边一定存在) 2 u v, 查询u到v的路 ...
随机推荐
- Linux基础——sar 查看网卡流量
sar -n DEV #查看当天从零点到当前时间的网卡流量信息 sar -n DEV 1 10 #每秒显示一次,共显示10次 sar -n DEV -f /var/log/sa/saxx #查看xx日 ...
- PHP-XML基于流的解析器及其他常用解析器
PHP中有两种主要的XML解析器 1)基于树的解析器.它是把整个文档存储为树的数据结构中,即需要把整个文档都加载到内存中才能工作.所以,当处理大型XML文档时候,性能剧减.SimpleXML和DOM扩 ...
- CodeIgniter 2.X 于 PHP5.6 兼容错误
本篇文章由:http://xinpure.com/codeigniter-2-x-to-php5-6-compatible-error/ CI 3.0 已兼容此问题 在代码迁移的过程中,遇到了一个 P ...
- 安装Spring+搭建Spring开发环境
https://blog.csdn.net/csdnsjg/article/details/80152815 https://jingyan.baidu.com/article/219f4bf798e ...
- 新标准C++程序设计读书笔记_继承和多态
简单继承的例子: #include <iostream> #include <string> using namespace std; class CStudent { pri ...
- iOS直播-播放基于RTMP协议的视频
iOS直播-播放基于RTMP协议的视频 流媒体协议介绍 1. 伪流媒体: 渐进式下载 : 边下边存, 文件会保存 使用http协议,也能够实现视频播放, 也能快进快退等, 体验上跟流媒体很像. 优酷, ...
- hdu5536 Chip Factory 字典树+暴力 处理异或最大 令X=(a[i]+a[j])^a[k], i,j,k都不同。求最大的X。
/** 题目:hdu5536 Chip Factory 链接:http://acm.hdu.edu.cn/showproblem.php?pid=5536 题意:给定n个数,令X=(a[i]+a[j] ...
- Hadoop中的RPC机制
1. RPC——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议.RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据.在OSI ...
- [转]jna模拟指针开辟空间,数组首地址获取值
http://blog.csdn.net/zhuzhichao0201/article/details/5817819 不是很明白,先记在这里 ———————————————————————————— ...
- struts中如何实现国际化,涉及哪些文件?
struts中如何实现国际化,涉及哪些文件? 解答:“国际化”是指一个应用程序在运行时能够根据客户端请求所来自的国家/地区.语言的不同而显示不同的用户界面.Struts框架通过使用<bean:m ...