题意: 给出一个序列,给出一个k,要求给出一个划分方案,使得连续区间内不同的数不超过k个,问划分的最少区间个数,输出时将k=1~n的答案都输出

比赛的时候想的有点偏,然后写了个nlog^2n的做法,T了

赛后发现有更加巧妙的做法

题解:

首先,可以贪心地想

也就是说从第一个数开始,每个区间都尽量往后选,直到不能选为止,可以证明这样是最优的

那么如果按照这个方案,实际上区间的选取都是固定的。

所以位置为i的数有可能是k=1,k=2....k=t的起点

如果当前位置是i,我们考虑如何更新答案

首先对答案有影响的只有在i右边的不同类别的第一个数,比如i右边有1 2 3 1 2,那么有影响的只有前3个数

所以考虑动态插入一个树状数组

也就是说当前位置是i,k=t,那么k=t的下一个区间的位置就是去找树状数组内的一个区间,内部有t个不同的数(树状数组也可以查询这个问题)

然后从1到n枚举区间的起点,过程中更新k=t的下一个位置,并在每个位置用vector存包含了k为若干值的情况

(可以证明vector最多存nlogn个点,n+n/2+n/3+....+n/n约等于nlogn)

可以使用一个数组next存下一个位置的情况,也可以使用set来维护这个位置信息。

代码如下

#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
#define pb push_back
using namespace std;
const int maxn = 1e5 + ;
int c[maxn], ans[maxn], a[maxn];
set<int> S[maxn];
vector<int> L[maxn];
int n;
void Modify(int x, int s){
for(; x <= n; x += x&(-x)) c[x] += s;
}
int Find(int x){ //实际上只找x-1个数字
int p = ;
for(int i = ; i >= ; i--){
if(p + (<<i) <= n && c[p + (<<i)] < x) {
x -= c[p + (<<i)];
p += (<<i);
}
}
return p+;
} void gao(int i){
if(!S[i].empty()){
Modify(*S[i].begin(), );
S[i].erase(*S[i].begin());
}
} int main()
{
scanf("%d", &n);
for(int i = ; i <= n; i++) scanf("%d", a+i), S[a[i]].insert(i);
for(int i = ; i <= n; i++){
L[].pb(i);
gao(i);
}
for(int i = ; i <= n; i++){
for(auto x : L[i]){
int y = Find(x+);
L[y].pb(x);
ans[x]++;
}
Modify(i, -);
gao(a[i]);
}
for(int i = ; i <= n; i++) printf("%d ", ans[i]);
}

Codeforces Round #401 (Div. 1) C(set+树状数组)的更多相关文章

  1. CF Educational Codeforces Round 10 D. Nested Segments 离散化+树状数组

    题目链接:http://codeforces.com/problemset/problem/652/D 大意:给若干个线段,保证线段端点不重合,问每个线段内部包含了多少个线段. 方法是对所有线段的端点 ...

  2. Educational Codeforces Round 10 D. Nested Segments 离线树状数组 离散化

    D. Nested Segments 题目连接: http://www.codeforces.com/contest/652/problem/D Description You are given n ...

  3. Educational Codeforces Round 10 D. Nested Segments 【树状数组区间更新 + 离散化 + stl】

    任意门:http://codeforces.com/contest/652/problem/D D. Nested Segments time limit per test 2 seconds mem ...

  4. Educational Codeforces Round 8 E. Zbazi in Zeydabad 树状数组

    E. Zbazi in Zeydabad 题目连接: http://www.codeforces.com/contest/628/problem/D Description A tourist wan ...

  5. HDU5465/BestCoder Round #56 (div.2) 二维树状数组

    Clarke and puzzle 问题描述 克拉克是一名人格分裂患者.某一天,有两个克拉克(aa和bb)在玩一个方格游戏. 这个方格是一个n*mn∗m的矩阵,每个格子里有一个数c_{i, j}c​i ...

  6. Codeforces Round #401 (Div. 2) 离翻身就差2分钟

    Codeforces Round #401 (Div. 2) 很happy,现场榜很happy,完全将昨晚的不悦忘了.终判我校一片惨白,小董同学怒怼D\E,离AK就差一个C了,于是我AC了C题还剩35 ...

  7. Codeforces 703D Mishka and Interesting sum(树状数组+扫描线)

    [题目链接] http://codeforces.com/contest/703/problem/D [题目大意] 给出一个数列以及m个询问,每个询问要求求出[L,R]区间内出现次数为偶数的数的异或和 ...

  8. CodeForces 380C Sereja and Brackets(扫描线+树状数组)

    [题目链接] http://codeforces.com/problemset/problem/380/C [题目大意] 给出一个括号序列,求区间内左右括号匹配的个数. [题解] 我们发现对于每个右括 ...

  9. Codeforces 703D Mishka and Interesting sum 离线+树状数组

    链接 Codeforces 703D Mishka and Interesting sum 题意 求区间内数字出现次数为偶数的数的异或和 思路 区间内直接异或的话得到的是出现次数为奇数的异或和,要得到 ...

随机推荐

  1. 【操作系统作业—lab1】linux shell脚本 遍历目标文件夹和所有文件 | 包括特殊字符文件名的处理

    要求:写一个linux bash脚本来查看目标文件夹下所有的file和directory,并且打印出他们的绝对路径. 运行command:./myDir.sh  input_path  output_ ...

  2. GET POST 请求的详细区别

    前言: 作为最常见的请求方式 在面试很有可能会被问到 所以在这里做一个简单总结 GET get方法向页面请求发送参数 地址和参数之间用?进行分割 例如 localhost:80/download.ht ...

  3. js 节点

    var chils= s.childNodes; //得到s的全部子节点 var par=s.parentNode;  //得到s的父节点 var ns=s.nextSbiling;  //获得s的下 ...

  4. 简单整理React的Context API

    之前做项目时经常会遇到某个组件需要传递方法或者数据到其内部的某个子组件,中间跨越了甚至三四层组件,必须层层传递,一不小心哪层组件忘记传递下去了就不行.然而我们的项目其实并没有那么复杂,所以也没有使用r ...

  5. vue 项目如何使用微信分享接口

    首先做微信网页都要接入微信sdk: 安装sdk npm install weixin-js-sdk --save 具体可以查看微信公众平台技术文档:https://mp.weixin.qq.com/w ...

  6. Yarn 调度器Scheduler详解

    理想情况下,我们应用对Yarn资源的请求应该立刻得到满足,但现实情况资源往往是有限的,特别是在一个很繁忙的集群,一个应用资源的请求经常需要等待一段时间才能的到相应的资源.在Yarn中,负责给应用分配资 ...

  7. itop-4412开发板学习-内核信号量

    1. 翻翻书看下,linux提供两种信号量,内核信号量,由内核控制路径使用,System V IPC信号量,由用户态进程使用.下面的就是内核部分的信号量.内核信号量类似于自旋锁,当锁关闭着时,不允许内 ...

  8. leetcode笔记--2 reverse string

    my answer: 出错点:new_list[s] = list_s[u-1-s] 这样会出错, 重点:(1) map(str, s) 函数的使用,例:ls = [1,2,3]rs = map(st ...

  9. MQTT 开源代理mosquitto的网络层封装相当sucks

    最近学习MQTT协议,选择了当前比较流行的MQTT Broker “mosquitto”,但是在阅读代码过程中发现其网络底层库封装的相当差劲. 对于MQTT协议的变长头长度的读取上,基本上采取每次一个 ...

  10. Java并发(多线程)

    一.多线程的基本概念 1.什么是进程.多进程有什么作用? 大家都使用计算机,当我们打开某一个软件的时候,其实就是启动了一个进程,可以打开任务管理器看看,我们打开的每一个软件,都是一个进程,在同一个操作 ...