题解-Happy New Year

Happy New Year

给定 \(n\),\(m\) 和 \(k\)。有一个序列 \(a\{m\}\) 初始值为 \(0\)。有 \(n\) 种操作,每种可以使 \([L_i,R_i]\) 区间序列值 \(+1\)。每个操作最多用 \(1\) 次(可以不用)。保证对于每个 \(i(1\le i\le n)\) 最多存在 \(k\) 个不同的 \(j\) 满足 \(i\in[L_j,R_j]\)。求最后的序列中奇数最多个数。

数据范围:\(1\le n\le 10^5\),\(1\le m\le 10^9\),\(1\le k\le 8\)。


状压 \(\texttt{dp}\) 水题,连我这个小蒟蒻都几下就做出来了。


从数据范围和时间复杂度入手分析题目:

  1. 首先看到 \(n\) 的大小,就知道复杂度中要带个 \(n\)。
  2. 时间复杂度中不能带 \(m\),而且这题也不能二分倍增分治之类的,所以也不带 \(\log m\)。
  3. 时间复杂度可以带 \(k\),甚至还可以带个 \(2^k\)。考虑到这个 \(k\) 真是小到离奇,于是想着带 \(2^k\)——写个状压 \(\texttt{dp}\)。

将每个区间 \(i\) 的 \(L_i\) 和 \(R_i+1\) 带信息放进数组 \(p\) 中,按如下的 \(\texttt{cmp}\) 排序:

struct point{
int op,w,d; //如果是L_i,op=1,w=L_i;如果是R_i,op=-1,w=R_i+1。d=i
point(int OP=0,int W=0,int D=0){op=OP,w=W,d=D;}
};
int cmp(point x,point y){
if(x.w==y.w) return x.op<y.op; //※先处理R_i,防止中途当前覆盖区间数 >k
return x.w<y.w; //按大小排序
}

从左到右枚举每个端点,将当前覆盖着的区间放进数组 \(d\)。

令 \(f_{i,j}\) 表示到第 \(i\) 个端点,选择的区间覆盖状态为 \(j\) 的最大答案。

\(j\) 中二进制下如果第 \(at-1\) 位是 \(1\),则表示选择了区间 \(d_{at}\) 并且 \(d_{at}\) 正覆盖在当前端点上。

如果 \(at\) 表示该端点在数组 \(d\) 中的位置,那么相邻两个端点之间可以如下递推:

\[\begin{split}
&\textbf{if}\ [p_i. op=1]:\\
&\qquad \textbf{if}\ [at\in j]:f_{i,j}=\max\{f_{i,j},f_{i-1,j}+[|j|\in \mathbb{odd}](p_i. w-p_{i-1}. w)\}\\
&\qquad \textbf{if}\ [at\notin j]:f_{i,j\cup\{at\}}=\max\{f_{i,j\cup\{at\}},f_{i-1,j}+[|j|\in \mathbb{odd}](p_i.w-1-p_{i-1}.w)+[(|j|+1)\in \mathbb{odd}]\}\\
&\textbf{if}\ [p_i. op=-1]:\\
&\qquad \textbf{if}\ [at\notin j]:\\
&\qquad \qquad f_{i,j}=\max\{f_{i,j},f_{i-1,j}+[|j|\in \mathbb{odd}](p_i.w-p_{i-1}.w)\}\\
&\qquad \qquad f_{i,j}=\max\{f_{i,j},f_{i-1,j\cup at}+[(|j|+1)\in \mathbb{odd}](p_i.w-1-p_{i-1}.w)\}+[|j|\in\mathbb{odd}]\}\\
\end{split}
\]

最后的答案就是 \(f_{2n,\varnothing}\)。


小蒟蒻怕自己讲不清楚,于是做了个动画:

Input

3 10 2
2 5
5 7
8 9


时间复杂度 \(\Theta(n2^k)\),空间复杂度 \(\Theta(n2^k)\)。


Code

蒟蒻的做法比较玄学,但是又很简单,所以放个代码走人吧。

#include <bits/stdc++.h>
using namespace std; //Start
#define lng long long
#define db double
#define mk make_pair
#define pb push_back
#define fi first
#define se second
#define rz resize
const int inf=0x3f3f3f3f;
const lng INF=0x3f3f3f3f3f3f3f3f; //Data
const int N=1e5,K=8;
int n,m,k;
int l[N+7],r[N+7];
struct point{
int op,w,d;
point(int OP=0,int W=0,int D=0){op=OP,w=W,d=D;}
};
int cmp(point x,point y){
if(x.w==y.w) return x.op<y.op;
return x.w<y.w;
}
int pcnt;
point p[(N<<1)+7]; //DP
int d[K+7],one[(1<<K)+7];
int f[(N<<1)+7][(1<<K)+7];
void Max(int&x,int y){x=max(x,y);}
int DP(){
int ful=(1<<k)-1;
for(int i=1;i<=ful;i++) one[i]=one[i-(i&-i)]+1;
for(int i=0;i<=pcnt;i++)
for(int j=0;j<=ful;j++) f[i][j]=-inf;
f[0][0]=0;
for(int j=1;j<=k;j++) d[j]=-1;
int now=0;
for(int i=1;i<=pcnt;i++){
int at=-1;
if(p[i].op==1){
for(int j=1;j<=k;j++)
if(d[j]==-1){at=j,d[j]=p[i].d;break;}
assert(~at);
for(int j=0;j<=now;j++)if((j&now)==j){
Max(f[i][j],f[i-1][j]+(one[j]&1)*(p[i].w-p[i-1].w));
Max(f[i][j|(1<<(at-1))],f[i-1][j]+(one[j]&1)*(p[i].w-1-p[i-1].w)+((one[j]+1)&1));
}
now|=(1<<(at-1));
} else {
for(int j=1;j<=k;j++)
if(d[j]==p[i].d){at=j,d[j]=-1;break;}
assert(~at);
now^=(1<<(at-1));
for(int j=0;j<=now;j++)if((j&now)==j){
Max(f[i][j],f[i-1][j]+(one[j]&1)*(p[i].w-p[i-1].w));
Max(f[i][j],f[i-1][j|(1<<(at-1))]+((one[j]+1)&1)*(p[i].w-1-p[i-1].w)+(one[j]&1));
}
}
}
return f[pcnt][0];
} //Main
int main(){
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++){
scanf("%d%d",&l[i],&r[i]);
p[++pcnt]=point(1,l[i],i);
p[++pcnt]=point(-1,r[i]+1,i);
}
sort(p+1,p+pcnt+1,cmp);
printf("%d\n",DP());
return 0;
}

祝大家学习愉快!

题解-Happy New Year的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

  10. JSOI2016R3 瞎BB题解

    题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...

随机推荐

  1. gdb调试入门(上)

    一.什么是gdb:gdb是GNU debugger的缩写,是编程调试工具二.gdb功能:1.启动程序,可根据用户要求随心所欲的运行程序(比如带参数)2.可让被调试的程序在用户指定的调试的断点处停住3. ...

  2. Python的ConfigParser模块读取ini配置文件 报错(持续更新总结)

    1.ConfigParser.MissingSection什么的错误巴拉巴拉一堆,其实根本上就是没有读到配置文件,然后我去检查了一遍路径,发现没有问题,我是将文件的路径作为一个字符串拼接好传到另一个专 ...

  3. TypeError: Cannot read property 'Component' of undefined

    继续跟着阮一峰的教程走,下面写到PropTypes的getDefaultProps时,又出现了问题,基于上一个createClass的报错换成了Component写法 错误描述: 解决方法:引入rea ...

  4. Integer 错误的加锁

    多线程同时访问一个Integer加锁的问题,程序运行和想要的结果相差甚远,让我百思不得其解,就下来研究了一下: 在进行多线程同步时,加锁是保证线程安全的重要手段之一.synchronized是大多数程 ...

  5. python+selenium+chromedriver抓取shodan搜索结果

    作用:免积分抓取shodan的搜索结果,并把IP保存为txt 前提: ①shodan会员(ps:黑色星期五打折) ②安装有python27 ③谷歌浏览器(ps:版本一定要跟chromedriver匹配 ...

  6. Codeforces1009F Dominant Indices

    dsu on tree 题目链接 点我跳转 题目大意 给定一棵以 \(1\) 为根,\(n\) 个节点的树.设\(d(u,x)\) 为 \(u\) 子树中到 \(u\) 距离为 \(x\) 的节点数. ...

  7. 如何用Prometheus监控十万container的Kubernetes集群

    概述 不久前,我们在文章<如何扩展单个Prometheus实现近万Kubernetes集群监控?>中详细介绍了TKE团队大规模Kubernetes联邦监控系统Kvass的演进过程,其中介绍 ...

  8. Mac读写ntfs软件究竟哪一款适合我们?

    生活中我们免不了会使用一些硬盘设备来存储文件或者是数据,然而绝大多数的移动硬盘都是ntfs格式.Mac读写ntfs软件有很多,究竟哪一款适合我们? 首先,我们一起了解一下什么是ntfs格式.ntfs, ...

  9. mongodb 副本集之入门篇

    作者: 凹凸曼-军军 前言:mongodb 因为高性能.高可用性.支持分片等特性,作为非关系型数据库被大家广泛使用.其高可用性主要是体现在 mongodb 的副本集上面(可以简单理解为一主多从的集群) ...

  10. 宝塔Linux面板安装

    宝塔linux6.0版本是基于centos7开发的,务必使用centos7.x 系统 提示:Centos官方已宣布在2020年停止对Centos6的维护更新,各大软件开发商也逐渐停止对Centos6的 ...