二分栈,就是通过二分维护的栈

(逃)

解析

本题的决策单调性可以说是显然
但是本题是同维度(其实只有一维)自左向右转移,分治的写法是不能奏效的
所以我们使用决策点调性的另一种实现方法:二分栈
具体来说,维护[1,n]各自的最优转移点
一开始的转移点全是0,把三元组(0,1,n)(0,1,n)(0,1,n)push入栈,分别表示转移点和左右端点
然后从1扫到n
扫到i的时候,利用i当前的最优决策点进行转移
然后尝试更新后面的最优决策点
不断取出栈顶,如果栈顶区间在 l 的位置还是不如当前的转移,显然这个区间没有用了,弹出栈顶
然后对于无法使之弹出的区间,二分出其与自己在何时会发生最优转移的变化,如果这个变化的位置pl<=n,把(i,pl,n)(i,pl,n)(i,pl,n)入栈,并把之前的栈顶区间右端点改为pl-1
然后就解决啦!

注意事项

至少是我易错的

二分的时候当calc相等的时候不能草率!可能是都返回了inf,所以要按照这个时候那个绝对值的正负分类讨论

while(st<ed){int mid=(st+ed)>>1;ll a=calc(j,mid),b=calc(i,mid);if(a<b||(a==b&&sum[mid]-sum[i]-l-1>0)) ed=mid;else st=mid+1;
}

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define il inline
#define debug(a) fprintf(stderr,a)
const int N=1e5+100;
const int M=3e6+100;
const int mod=998244353;
inline ll read(){ll x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=x*10+c-'0';c=getchar();}return x*f;
}
int n,p,l;
ll f[N],sum[N];
ll ksm(ll x,ll k){if(x<0) x=-x;ll res=1;while(k){if(k&1) res*=x;x=x*x;k>>=1;}return res;
}
inline ll calc(int i,int j){//printf("  calc:%d %d jd=%lld>%lf\n",i,j,abs(sum[j]-sum[i]-l-1),(1.0*log(1e18-f[i])/log(p)));if(abs(sum[j]-sum[i]-l-1)&&(f[i]>1e18||p>1.0*log(2e18-f[i])/log(abs(sum[j]-sum[i]-l-1)))) return 2e18+1;else return f[i]+ksm(sum[j]-sum[i]-l-1,p);
}
#define pr pair<int,int>
#define mkp make_pair
pr q[N];//id st
int st,ed;
char s[N][33];
int pre[N];
int find(int i,int j){int st=j+1,ed=n+1;while(st<ed){int mid=(st+ed)>>1;ll a=calc(j,mid),b=calc(i,mid);if(a<b||(a==b&&sum[mid]-sum[i]-l-1>0)) ed=mid;else st=mid+1;}//printf("find:i=%d j=%d st=%d\n",i,j,st);return st;
}
int a[N],b[N],tot;
int main(){#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);#endifint T=read();while(T--){n=read();l=read();p=read();for(int i=1;i<=n;i++){scanf(" %s",s[i]+1);sum[i]=sum[i-1]+strlen(s[i]+1)+1;//printf("i=%d sum=%d\n",i,sum[i]);}st=ed=1;q[1]=mkp(0,1);int flag=0;for(int i=1;i<=n;i++){while(st<ed&&q[st+1].second<=i) st++;int now=q[st].first;pre[i]=now;f[i]=calc(now,i);//printf("i=%d now=%d f=%lld\n",i,now,f[i]);while(st<=ed){int pl=find(q[ed].first,i);if(pl<=q[ed].second) ed--;else{if(pl<=n) q[++ed]=mkp(i,pl);break;}}if(st>ed) q[++ed]=mkp(i,i+1);}//debug("ok");if(f[n]>1e18) printf("Too hard to arrange\n");else{printf("%lld\n",f[n]);tot=0;int pl=n;while(pl){b[++tot]=pl;pl=pre[pl];a[tot]=pl+1;}for(int i=tot;i>=1;i--){for(int j=a[i];j<=b[i];j++){printf("%s",s[j]+1);if(j!=b[i]) putchar(' ');}printf("\n");}}printf("--------------------\n");}return 0;
}
/*
3 1
3 1 33 2
1 1 2
3 1 3
*/

洛谷P1912:诗人小G(二分栈、决策单调性)相关推荐

  1. P1912 [NOI2009]诗人小G

    P1912 [NOI2009]诗人小G 思路: 平行四边形不等式优化dp 因为f(j, i) = abs(sum[i]-sum[j]+i-j-1-l)^p 满足平行四边形不等式 j < i f( ...

  2. 决策单调性Ⅰ:四边形不等式(bzoj 1563: [NOI2009]诗人小G)

    题目描述: 给出n个数字和常数L,你可以任意合并相邻的两个数字a[x]和a[x+1],并得出一个新的数a[x]+a[x+1]+1,一通合并后得到一个有若干个数的序列,这个序列的不协调值为∑|(a[i] ...

  3. 【NOI 2009】诗人小G

    [NOI 2009]诗人小G Problem Description 小 \(G\) 是一个出色的诗人,经常作诗自娱自乐.但是,他一直被一件事情所困扰,那就是诗的排版问题. 一首诗包含了若干个句子,对 ...

  4. 洛谷P1462 通往奥格瑞玛的道路 二分答案+最短路SPFA

    洛谷P1462 通往奥格瑞玛的道路 二分答案+最短路SPFA 二分交费最多的一次的钱数 然后只将符合要求的边加入图中 如果到终点的最短路大于等于血量 或者直接起点不能到达终点 那么说明不符合要求 需要 ...

  5. 【洛谷4005】小Y和地铁(搜索)

    [洛谷4005]小Y和地铁(搜索) 题面 洛谷 有点长. 题解 首先对于需要被链接的两个点,样例中间基本上把所有的情况都给出来了. 但是还缺了一种从下面绕道左边在从整个上面跨过去在从右边绕到下面来的情 ...

  6. NOI2009 诗人小G

    题目 小G是一个出色的诗人,经常作诗自娱自乐.但是,他一直被一件事情所困扰,那就是诗的排版问题. 一首诗包含了若干个句子,对于一些连续的短句,可以将它们用空格隔开并放在一行中,注意一行中可以放的句子数 ...

  7. 洛谷 1373 dp 小a和uim之大逃离 良心题解

    洛谷 1373 dp 这题还不算太难,,当初看的时候不是很理解题意,以为他们会选择两条不同的路径,导致整体思路混乱 传送门 其实理解题意和思路之后还是敲了不短的时间,一部分身体原因再加上中午休息不太好 ...

  8. 一个诗人的一生——诗人小G的人生

    看到群里有人说周末作文是以一个诗人的一生为题写作文-于是就突发脑洞写了这么个东西. 哇发出来好羞耻啊(x 诗与人生 某一天,在某一个地方,小G诞生了. 小G原本是有自己的名字的,但是在某一天之后,他就 ...

  9. 【洛谷1361】 小M的作物(最小割)

    传送门 洛谷 Solution 这是一个比较实用的套路,很多题目都有用,而且这个套路难以口胡出来. 考虑把每一个附加贡献重新建一个点,然后向必需的点连边,流量为val. 然后直接种植的从源点向这个点连 ...

最新文章

  1. attention seq2seq transformer bert 学习总结 _20201107
  2. (已解决)ImportError attempted relative import with no known parent package
  3. NLP自然语言常见问题及相关模型训练数据格式示例
  4. Java内存泄漏、性能优化、宕机死锁的N种姿势
  5. 《信息存储与管理(第二版):数字信息的存储、管理和保护》—— 2.12 闪存盘简介...
  6. linux location root访问文件夹404_如何使网站支持https访问?nginx配置https证书
  7. .net项目开发工具(v2.0)功能完善专帖
  8. 12_04_Linux软件管理之四yum
  9. java - 判断任意一天是这年的第几天
  10. python推荐系统设置_用Python构建你自己的推荐系统
  11. LogStash实现MySQL数据增量同步到ElasticSearch
  12. ExtJS 组件添加子组件
  13. 密码字典生成工具汇总
  14. 行为画像分析 行业客户画像 行业用户画像
  15. 锂镍钴价格齐飞,新能源汽车涨价潮何时休?
  16. TheChroniclesOfNarnia写作年代
  17. Win10禁用缩略图解决资源管理器老是重启
  18. win10电脑连接蓝牙请检查PIN并重新连接
  19. 数据类型_function_函数概论
  20. 51单片机I/O端口的结构和工作原理

热门文章

  1. sql企业管理器_Valentina Studio for mac(开源数据库管理器)
  2. c语言while运行出现错误,【图片】为什么我的while(1)不执行啊?【c语言吧】_百度贴吧...
  3. antd request 通过jsessionid传参数_Umi-request源码阅读
  4. java 最好 入门_C++和Java哪个比较好入门?初学者该如何选择?
  5. as本地仓库更改_将gitee仓库连接GitHub Desktop。新建更改仓库并上传至gitee。
  6. python实例化对象是什么意思_请帮我理解python对象的实例化.
  7. KMP模式串匹配+Compress Words CodeForces - 1200E
  8. 数据结构与算法--复杂链表的复制
  9. 海外服务器维护,海外服务器运行不正常的原因是什么?
  10. python正态分布函数_python3-正态分布