bzoj 1780
这是一道环上的问题,我们先将一个环展开,再复制一次。
这样,任何一个合法方案一定对应在转换后的序列的一些连续的区间,使得它们的并的长度大于等于圈长。
然后,我们将区间合并一下(就是将一些被其他区间包含的区间去掉)。
假设某个答案的区间是r1,r2,r3,...rk,我们可以让ri为"与ri-1连接的右端点最靠右的区间“,明显这样不会不原来的答案劣。
所以,一旦确定了起点,那么在该起点的情况下最优的覆盖圆环的方案就确定了,确定了区间,我们可以用倍增的思想来判断一串连续区间覆盖len最少需要多少个,(有点像跳跃式的LCA求法中用倍增的思想)。这个O(logn)可搞,然后枚举起点是O(n),总的复杂度是O(nlogn)。
/**************************************************************
Problem: 1780
User: idy002
Language: C++
Result: Accepted
Time:2124 ms
Memory:33796 kb
****************************************************************/ #include <cstdio>
#include <vector>
#include <algorithm>
#define fprintf(...)
#define maxn 200010
#define maxp 18
using namespace std; struct Rng {
int lf, rg;
Rng(){}
Rng( int lf, int rg ):lf(lf),rg(rg){}
bool operator<( const Rng &b ) const { return lf<b.lf || (lf==b.lf&&rg>b.rg); }
}; int len, n;
Rng rng[maxn]; int tot;
vector<int> stk;
bool mark[maxn];
int nxt[maxn][maxp+], dis[maxn][maxp+]; int main() {
scanf( "%d%d", &len, &n );
for( int i=,lf,ln; i<=n; i++ ) {
scanf( "%d%d", &lf, &ln );
rng[++tot] = Rng(lf,lf+ln);
}
for( int i=,otot=tot; i<=otot; i++ )
rng[++tot] = Rng( rng[i].lf+len, rng[i].rg+len );
sort( rng+, rng++tot );
for( int i=; i<=tot; i++ )
if( !mark[i] ) {
stk.push_back( i );
fprintf( stderr, "Got [%d,%d]\n", rng[i].lf, rng[i].rg );
for( int j=i+; j<=tot; j++ )
if( rng[j].rg<=rng[i].rg ) mark[j]=true;
else break;
}
for( int t=; t<stk.size(); t++ ) {
int u=stk[t];
nxt[u][] = u;
dis[u][] = ;
for( int tt=t+; tt<stk.size(); tt++ ) {
int v=stk[tt];
if( rng[v].lf<=rng[u].rg ) {
nxt[u][] = v;
dis[u][] = rng[v].rg-rng[u].rg;
} else break;
}
}
for( int p=; p<=maxp; p++ )
for( int t=; t<stk.size(); t++ ) {
int u=stk[t];
nxt[u][p] = nxt[nxt[u][p-]][p-];
dis[u][p] = dis[u][p-]+dis[nxt[u][p-]][p-];
}
/*
for( int t=0; t<stk.size(); t++ ) {
int u=stk[t];
fprintf( stderr, "from [%d,%d]: \n", rng[u].lf, rng[u].rg );
for( int p=0; p<=5; p++ )
fprintf( stderr, "nxt[%d]=[%d,%d] dis[%d]=%d\n", p, rng[nxt[u][p]].lf, rng[nxt[u][p]].rg, p, dis[u][p] );
fprintf( stderr, "\n" );
}
*/
int ans=n;
for( int t=; t<stk.size(); t++ ) {
int u=stk[t];
int remain=len-(rng[u].rg-rng[u].lf);
int tans = ;
for( int p=maxp; dis[u][] && dis[u][]<remain; p-- )
if( dis[u][p]<remain ) {
remain-=dis[u][p];
tans += <<p;
u=nxt[u][p];
}
tans++;
if( dis[u][]== ) continue;
fprintf( stderr, "from [%d,%d] got ans %d\n", rng[u].lf, rng[u].rg, tans );
if( tans<ans ) ans=tans;
}
printf( "%d\n", ans );
}
bzoj 1780的更多相关文章
- bzoj usaco 金组水题题解(2.5)
bzoj 2197: [Usaco2011 Mar]Tree Decoration 树形dp..f[i]表示处理完以i为根的子树的最小时间. 因为一个点上可以挂无数个,所以在点i上挂东西的单位花费就是 ...
- BZOJ 2127: happiness [最小割]
2127: happiness Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1815 Solved: 878[Submit][Status][Di ...
- BZOJ 3275: Number
3275: Number Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 874 Solved: 371[Submit][Status][Discus ...
- BZOJ 2879: [Noi2012]美食节
2879: [Noi2012]美食节 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1834 Solved: 969[Submit][Status] ...
- bzoj 4610 Ceiling Functi
bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...
- BZOJ 题目整理
bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...
- 【sdoi2013】森林 BZOJ 3123
Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...
- 【清华集训】楼房重建 BZOJ 2957
Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些 ...
- 【splay】文艺平衡树 BZOJ 3223
Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 ...
随机推荐
- 深入理解Spring系列之五:BeanDefinition装载
转载 https://mp.weixin.qq.com/s/1_grvpJYe8mMIAnebMdz9Q 接上篇<深入理解Spring系列之四:BeanDefinition装载前奏曲>,进 ...
- Perl6多线程1 Thread : new / run
先看一个小例子: ) { #默认参数 say $name; } sub B(:name($name)) { #默认参数为 any say $name; } A(); A(); B(); B(name ...
- IT人员必备linux安全运维之Ssh用途、安全性、身份认证以及配置……【转】
SSH一般用途 提供shell,解决telnet不安全的传输 1.修改默认ssh默认端口 vi /etc/ssh/sshd_config 修改之后重启 >systemctl restart ss ...
- UVALive 5760 Alice and Bob
题意是黑板上有n个数\(S_i\).每次操作可以把其中一个数减1或者将两个数合并为一个数.一个数变为0时,则不能再对其操作. 思路是发现最大的可操作次数为\( \sum S_i\)+(n - 1).\ ...
- AJP与HTTP比较和分析
系统环境: OS:Ubuntu 10.10 (2G) Servlet Container:tomcat-tomcat-7.0.23 (最大内存:default 256M maxThreads:50 ...
- ssh修改端口号并进行远程访问
ssh的访问如果都利用22端口,则会容易被攻击,修改一个端口号可增强一定的安全性 1. 修改配置文件sshd_config里端口号 [root@test ~]# vi /etc/ssh/sshd_co ...
- jQuery常用事件方法详解
目录 jQuery事件 ready(fn)|$(function(){}) jQuery.on() jQuery.click jQuery.data() jQuery.submit() jQuery事 ...
- 小技巧:tar命令打包目录时,排除文件和目录的命令
今天不巧要用上,百度. tar zcvf fd.tar.gz pardir --exclude=pardir/file1 --exclude=pardir/dir1
- GUC-1 volatile
/* * 一.volatile 关键字:当多个线程进行操作共享数据时,可以保证内存中的数据可见. * 相较于 synchronized 是一种较为轻量级的同步策略. * * 注意: * 1. vola ...
- css3 box-sizing属性值详解
box-sizing属性可以为三个值之一:content-box(default),border-box,padding-box. content-box,border和padding不计算入widt ...