题目

  点这里看题目。

分析

  先特判掉\(K=2\)的情况。

  首先可以考虑到一个简单 DP :

  \(f(i)\):前\(i\)张牌的最大贡献。

  转移可以\(O(n^2)\)地枚举区间众数,但它不存在决策单调性,众数查询也很难优化。

  考虑另一种转移。我们对于\(f(i)\),只取它结尾的点数的后缀

\[f(i)=\max_{1\le j\le i,a_j=a_i}\{f(j-1)+s(i)-s(j)+1\}
\]

  其中的\(s_i\)为前\(i\)张牌里与第\(i\)张点数相同的牌的张数。

  这个转移从全局来看也不存在单调性,但实际上,它具有部分单调性

  对于所有的结尾点数相同的\(f\),除开\(i=j\)的转移,剩下的转移中它的最优决策点与前面的结尾点数相同的\(f\)的已有决策点是单调不增的

  利用好这个性质,我们就可以对于每个颜色维护一个\(i\not=j\)的转移的单调栈,计算新的值的时候把已有的不优的决策点弹掉,插入新的值的时候二分一下右边界,时间是\(O(n\log_2n)\)。

代码

#include <cmath>
#include <cstdio>
#include <vector>
using namespace std; const int MAXN = 1e6 + 5; template<typename _T>
void read( _T &x )
{
x = 0;char s = getchar();int f = 1;
while( s > '9' || s < '0' ){if( s == '-' ) f = -1; s = getchar();}
while( s >= '0' && s <= '9' ){x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar();}
x *= f;
} template<typename _T>
void write( _T x )
{
if( x < 0 ){ putchar( '-' ); x = ( ~ x ) + 1; }
if( 9 < x ){ write( x / 10 ); }
putchar( x % 10 + '0' );
} template<typename _T>
_T MAX( const _T a, const _T b )
{
return a > b ? a : b;
} vector<int> pos[MAXN]; double pw[MAXN], f[MAXN];
int stk[MAXN], but[MAXN], top[MAXN], rig[MAXN];
int A[MAXN], pre[MAXN], tot[MAXN], vised[MAXN];
int N, K; double getDP( const int i, const int j )
{
return f[j - 1] + pw[pre[i] - pre[j] + 1];
} int get( const int i, const int j )
{
int id = A[i];
int l = vised[id] - 1, r = pos[id].size() - 1, mid;
while( r - l > 1 )
{
mid = l + r >> 1;
if( getDP( pos[id][mid], i ) >= getDP( pos[id][mid], j ) ) l = mid;
else r = mid - 1;
}
if( getDP( pos[id][r], i ) >= getDP( pos[id][r], j ) ) return pos[id][r];
return pos[id][l];
} int main()
{
read( K ), read( N );
for( int i = 1 ; i <= N ; i ++ ) pw[i] = pow( i, 1.0 * K / 2 );
for( int i = 1 ; i <= N ; i ++ ) read( A[i] ), pre[i] = ++ tot[A[i]], pos[A[i]].push_back( i );
if( K == 2 ) { printf( "%.10lf\n", ( double ) N ); return 0; }
int siz = 0;
for( int i = 1 ; i <= N ; i ++ )
if( tot[i] )
but[i] = siz + 1, top[i] = siz, siz += tot[i];
int id;
for( int i = 1 ; i <= N ; i ++ )
{
f[i] = f[i - 1] + 1, id = A[i];
while( but[id] < top[id] && i > rig[top[id] - 1] ) top[id] --;
if( but[id] <= top[id] ) f[i] = MAX( f[i], getDP( i, stk[top[id]] ) );
while( but[id] < top[id] && get( i, stk[top[id]] ) >= rig[top[id] - 1] ) top[id] --;
if( but[id] <= top[id] ) rig[top[id]] = get( i, stk[top[id]] );
stk[++ top[id]] = i, rig[top[id]] = N;
vised[id] ++;
}
printf( "%.10lf\n", f[N] );
return 0;
}

[noi.ac省选模拟赛20200606]赌怪的更多相关文章

  1. NOI.AC省选模拟赛第一场 T1 (树上高斯消元)

    link 很容易对于每个点列出式子 \(f_{x,y}=(f_{x,y-1}+f_{x,y}+f_{x,y+1}+f_{x+1,y})/4\)(边角转移类似,略) 这个转移是相互依赖的就gg了 不过你 ...

  2. [NOI.AC省选模拟赛3.31] 星辰大海 [半平面交]

    题面 传送门 思路 懒得解释了......也是比较简单的结论 但是自己看到几何就退缩了...... 下周之内写一个计算几何的学习笔记! Code #include<iostream> #i ...

  3. [NOI.AC省选模拟赛3.31] 附耳而至 [平面图+最小割]

    题面 传送门 思路 其实就是很明显的平面图模型. 不咕咕咕的平面图学习笔记 用最左转线求出对偶图的点,以及原图中每个边两侧的点是谁 建立网络流图: 源点连接至每一个对偶图点,权值为这个区域的光明能量 ...

  4. [NOI.AC省选模拟赛3.30] Mas的童年 [二进制乱搞]

    题面 传送门 思路 这题其实蛮好想的......就是我考试的时候zz了,一直没有想到标记过的可以不再标记,总复杂度是$O(n)$ 首先我们求个前缀和,那么$ans_i=max(pre[j]+pre[i ...

  5. [NOI.AC省选模拟赛3.23] 染色 [点分治+BFS序]

    题面 传送门 重要思想 真的是没想到,我很久以来一直以为总会有应用的$BFS$序,最终居然是以这种方式出现在题目中 笔记:$BFS$序可以用来处理限制点对距离的题目(综合点分树使用) 思路 本题中首先 ...

  6. [NOI.AC省选模拟赛3.23] 集合 [数学]

    题面 传送门 一句话题意: 给定$n\leq 1e9,k\leq 1e7,T\leq 1e9$ 设全集$U=\lbrace 1,2,3,...n\rbrace $,求$(min_{x\in S}\lb ...

  7. [noi.ac省选模拟赛]第12场题解集合

    题目 比赛界面. T1 数据范围明示直接\(O(n^2)\)计算,问题就在如何快速计算. 树上路径统计通常会用到差分方法.这里有两棵树,因此我们可以做"差分套差分",在 A 树上对 ...

  8. [noi.ac省选模拟赛]第10场题解集合

    题目 比赛界面. T1 不难想到,对于一个与\(k\)根棍子连接的轨道,我们可以将它拆分成\(k+1\)个点,表示这条轨道不同的\(k+1\)段. 那么,棍子就成为了点与点之间的边.可以发现,按照棍子 ...

  9. [noi.ac省选模拟赛]第11场题解集合

    题目   比赛界面. T1   比较简单.容易想到是求鱼竿的最大独立集.由于题目的鱼竿可以被分割为二分图,就可以想到最大匹配.   尝试建边之后会发现边的数量不小,但联系题目性质会发现对于一条鱼竿,它 ...

随机推荐

  1. C# 数据操作系列 - 14 深入探索SqlSugar

    0.前言 在上一篇中,我们知道了如何使用SqlSugar,但是也只是简单的了解了如何使用,仿佛是套着镣铐行走,这明显不符合一个合格的程序员应有的素养.所以,这一篇我们将对其进行深挖,探究其背后的秘密. ...

  2. 纯python自研接口自动化脚本更新版本,让小白也能实现0到1万+的接口自动化用例

    查看完整文章点击原文链接:纯python自研接口自动化脚本更新版本,让小白也能实现0到1万+的接口自动化用例 你是否还在用postman\jmeter做接口自动化吗?用python的开源框架[unit ...

  3. SpringMVC笔记总结

    文章所有代码见:gitee 1.回顾MVC 1.1.什么是MVC MVC是模型(Model).视图(View).控制器(Controller)的简写,是一种软件设计规范. 是将业务逻辑.数据.显示分离 ...

  4. js 三级联动 1

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  5. 【转】团队项目的Git分支管理规范

    原文地址: http://blog.jboost.cn/git-branch.html 分支管理 创建项目时(一般是服务型项目,工具型或辅助型项目可以简单一些),会针对不同环境创建三个常设分支: de ...

  6. 抽象类(abstract class)与抽象方法

    package cm.aff.abst; /* abstract:抽象的,,可以修饰类,方法 1.修饰类: 抽象类: ①不能被实例化 ②有构造器的 ③凡是类都有构造器 ④抽象方法所修饰的类一定是抽象类 ...

  7. Android Studio常见对话框(普通对话框、单选对话框、多选对话框、进度条对话框、消息对话框、自定义对话框)

    Android Studio常见对话框(普通对话框.单选对话框.多选对话框.进度条对话框.消息对话框.自定义对话框) 1.普通对话框 2.单选对话框 3.多选对话框 4.进度条对话框 5.消息对话框 ...

  8. 一篇文章看清楚 Linux 的职业发展方向

    手机.汽车.甚至宇宙飞船,在今天的科技世界中,你几乎到处都能看到 Linux 的身影.前两天 SpaceX 成功将宇航员送入太空的猎鹰9号火箭与龙飞船用的也是 Linux的操作系统.身处与 Linux ...

  9. 1. vue文件结构

    1)这是文件规则 <template> <div > </div> </template> <script> Name:"当前的名 ...

  10. 【积累】如何优雅关闭SpringBoot Web服务进程

    1.使用ps ef查出进程对应的pid. 2.使用kill -15 pid结束进程. 为什么不使用kill -9 pid,个人理解kill -15 pid更优雅,能在结束进程前执行spring容器清理 ...