Codeforces 786C Till I Collapse
题意:
给出一个长度为n的序列,每个数值在1-n之间且为整数,现在要把这个序列划分为若干段,使得每一段的颜色种数不超过k,求最少的区间数目.对于从1到n的n种k的取值,分别输出这时的最少区间数目.
分析:
首先这个题很像HH的项链,而HH的项链的在线做法需要写可持久化线段树,我们自然想到这个题也需要可持久化线段树
考虑对于每个k分别求解.暴力的贪心做法是这样:从左端开始,每次找出一段尽量长的颜色种数不超过k的区间划分出来.如果颜色种数要求不超过k,那么划分的区间段数最多为n/k上取整.(k个元素一段即可).对于k的n种取值,一共最多要找nln(n)段区间.如果能在较低的复杂度(例如logn)内找出每一段区间,这个题就做出来了.
然后我的想法是类似bzoj4504 K个串,写了一发区间修改的可持久化线段树,然后每次在线段树上二分.Codeforces的官方题解大概相当于这个做法差分一下,不需要区间修改,只需要单点修改的可持久化线段树.
具体是:对于每个左端点L,我们求出一个数组f[L][],f[L][i]存储从L到i出现的不同颜色的种数(如果i<L那么f[L][i]=0).那么从F[L][]到F[L-1][],只有a[L-1]影响的一段区间的数值会+1,那么可以用可持久化线段树来维护这个序列.查询时如果二分答案,每次在线段树上查询是两个log,直接在线段树上二分(也就是在每个节点判断向左侧还是右侧递归求解)就是一个log的.我写了一发标记永久化.细节参见代码.
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=100005;
struct node{
int Max,mk;
node* ch[2];
node(){}
node(int x,int y){
ch[0]=ch[1]=0;Max=x;mk=y;
}
}t[maxn*60];int tsz=0;
node* root[maxn];
node* newnode(int x,int y){
t[++tsz]=node(x,y);return t+tsz;
}
int a[maxn];
int last[maxn];
void Insert(node* rt0,node* &rt,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr){
rt=newnode(rt0->Max+1,rt0->mk+1);
rt->ch[0]=rt0->ch[0];rt->ch[1]=rt0->ch[1];
}else{
rt=newnode(0,rt0->mk);
rt->ch[0]=rt0->ch[0];rt->ch[1]=rt0->ch[1];
int mid=(l+r)>>1;
if(ql<=mid)Insert(rt0->ch[0],rt->ch[0],l,mid,ql,qr);
if(qr>mid)Insert(rt0->ch[1],rt->ch[1],mid+1,r,ql,qr);
rt->Max=max(rt->ch[0]->Max,rt->ch[1]->Max)+rt0->mk;
}
}
int n;
int query(node* rt,int l,int r,int lim,int pre){
if(l==r){//printf("%d\n",pre);
if(pre+rt->Max>lim)return -1;
else return l;
}
int lmax=rt->ch[0]->Max+pre+rt->mk;
int mid=(l+r)>>1;
if(lmax>lim)return query(rt->ch[0],l,mid,lim,pre+rt->mk);
else if(lmax<lim)return query(rt->ch[1],mid+1,r,lim,pre+rt->mk);
int t=query(rt->ch[1],mid+1,r,lim,pre+rt->mk);
if(t==-1)return mid;
else return t;
}
int right(int s,int lim){
return query(root[s],1,n,lim,0);
}
int work(int lim){
int pt=1;
int ans=0;
while(pt<=n){
ans++;
pt=right(pt,lim)+1;//if(lim==1)printf("%d\n",pt);
}
return ans;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i)scanf("%d",a+i);
root[n+1]=newnode(0,0);
root[n+1]->ch[0]=root[n+1]->ch[1]=root[n+1];
for(int i=1;i<=n;++i)last[i]=n+1;
for(int i=n;i>=1;--i){
root[i]=root[i+1];
Insert(root[i],root[i],1,n,i,last[a[i]]-1);
last[a[i]]=i;
}
// printf("%d\n",query(root[1],1,n,1,0));return 0;
for(int i=1;i<=n;++i){
printf("%d ",work(i));
}
return 0;
}
Codeforces 786C Till I Collapse的更多相关文章
- Codeforces 786C Till I Collapse(树状数组+扫描线+倍增)
[题目链接] http://codeforces.com/contest/786/problem/C [题目大意] 给出一个数列,问对于不同的k,将区间划分为几个, 每个区间出现不同元素个数不超过k时 ...
- Codeforces 786C. Till I Collapse 主席树
题目大意: 给定一个长度为\(n\)的序列,要求将其划分为最少的若干段使得每段中不同的数字的种数不超过\(k\). 对于 \(k = 1 .. n\)输出所有的答案. \(n \leq 10^5\) ...
- Till I Collapse CodeForces - 786C (主席树区间加,二分最小值)
大意: 给定序列, 将序列划分为若干段, 使得每段不同数字不超过k, 分别求出k=1...n时的答案. 考虑贪心, 对于某个k 从1开始, 每次查询最后一个颜色数<=k的点作为一个划分, 直到全 ...
- Codeforces 786 C. Till I Collapse
题目链接:http://codeforces.com/contest/786/problem/C 大力膜了一发杜教的代码感觉十分的兹瓷啊! 我们知道如果$k$是给定的我们显然是可以直接一遍$O(n)$ ...
- CF786C Till I Collapse 整体二分+根号分治
题意:对于一个序列,假如说一个区间内最多能包含 $k$ 个不同的数,那么这个序列最少会被划分成几个区间 $?$ 输出 $k$ 为 $1\sim n$ 的答案. 我们每次选区间一定是贪心地将这个区间选地 ...
- [cf787E]Till I Collapse
考虑对询问分块,对于i<K的询问,暴力处理,时间复杂度为o(Kn):对于i>K的询问,发现答案都小于n/K且满足单调性,那么可以二分出每一段相同的答案,时间复杂度为$o(n^{2}log_ ...
- CF786C Till I Collapse
题目分析 首先,对于这道题,可以用贪心以一个\(O(n)\)的复杂度求解一个\(k\)的值 暴力是\(O(n^2)\)的复杂度,当然过不了. 我们手推一下样例,会发现,答案满足单调性,于是,果断想到二 ...
- Codeforces Round #406 (Div. 1)
B题打错调了半天,C题想出来来不及打,还好没有挂题 AC:AB Rank:96 Rating:2125+66->2191 A.Berzerk 题目大意:有一个东东在长度为n的环上(环上点编号0~ ...
- 【Codeforces Round #406 (Div. 2)】题解
The Monster 签到题,算一下b+=a和d+=c,然后卡一下次数就可以了. Not Afraid 只要一组出现一对相反数就是安全的. Berzerk 题意:[1,n],两个人轮流走,谁能走到1 ...
随机推荐
- TMDXEVM6678L EVM开发板初使用(1)
1. 板子上电风扇转个不停,震动很大. 2. 有点懵逼,第一步干啥,首先安装板子的软件开发包,资料下载地址http://www2.advantech.com/Support/TI-EVM/6678le ...
- 【Jmeter测试】如何使用CSV Data Set Config获取参数
Jmeter提供CSV Data Set Config作为参数获取的一种方式 1.文件名:csv文件的绝对路径2.文件编码:根据运行环境设置,个人常用的是mac和linux,所以这里选择UT ...
- 420. Count and Say【LintCode java】
Description The count-and-say sequence is the sequence of integers beginning as follows: 1, 11, 21, ...
- Centos安装Python3(自带pip和setuptools)
安装zlib相关依赖 解决zipimport.ZipImportError: can't decompress data和pip3 ssl证书问题 sudo yum -y install zlib* ...
- 云主机启动提示Booting from Hard Disk GRUB
版本:Openstack ocata 系统:centos7.3 环境:VMware workstation12 解决方法: 或者
- Testing Harbor REST API on Swagger
先贴官方地址,我的做法差不多 https://github.com/goharbor/harbor/blob/master/docs/configure_swagger.md 1.下载对应资源 wge ...
- Switch Game :因子数
A - Switch Game Problem Description There are many lamps in a line. All of them are off at first. A ...
- 3.10-通过requests、BeautifulSoup、webbrowser模块的相关方法,爬取网页数据示例程序(一)
import requests,bs4res=requests.get('https://www.hao123.com/')print('res对象的类型:',type(res))res.raise_ ...
- 【RL系列】SARSA算法的基本结构
SARSA算法严格上来说,是TD(0)关于状态动作函数估计的on-policy形式,所以其基本架构与TD的$v_{\pi}$估计算法(on-policy)并无太大区别,所以这里就不再单独阐述之.本文主 ...
- 关于 WebView 知识点的详解
什么是 WebView WebView 是手机中内置了一款高性能 webkit 内核浏览器,在 SDK 中封装的一个组件.没有提供地址栏和导航栏, WebView 只是单纯的展示一个网页界面.在开发中 ...