luogu P2344 奶牛抗议 DP 树状数组 离散化
P2344 奶牛抗议
最新讨论
- 暂时没有讨论
题目背景
Generic Cow Protests, 2011 Feb
题目描述
约翰家的N 头奶牛正在排队游行抗议。一些奶牛情绪激动,约翰测算下来,排在第i 位的奶牛的理智度为Ai,数字可正可负。
约翰希望奶牛在抗议时保持理性,为此,他打算将这条队伍分割成几个小组,每个抗议小组的理智度之和必须大于或等于零。奶牛的队伍已经固定了前后顺序,所以不能交换它们的位置,所以分在一个小组里的奶牛必须是连续位置的。除此之外,分组多少组,每组分多少奶牛,都没有限制。
约翰想知道有多少种分组的方案,由于答案可能很大,只要输出答案除以1000000009 的余数即可。
输入输出格式
输入格式:
• 第一行:单个整数N,1 ≤ N ≤ 100000
• 第二行到第N + 1 行:第i + 1 行有一个整数Ai,−10^5 ≤ Ai ≤ 10^5
输出格式:
单个整数:表示分组方案数模1000000009 的余数
输入输出样例
4 2 3 -3 1
4
说明
解释:如果分两组,可以把前三头分在一组,或把后三头分在一组;如果分三组,可以把中间两头分在一组,第一和最后一头奶牛自成一组;最后一种分法是把四头奶牛分在同一组里。
Solution
用f[i]表示前I头cows的分组方案数,很容易得到DP方程:
边界
然后sum部分可以用前缀和维护,朴素的DP 大约是所以会TLE两个CASES
1 const p=1000000009; 2 var 3 n,i,j:longint; 4 a,s,f:array[0..100000] of longint; 5 6 function sum(i,j:longint):longint; 7 begin 8 exit(s[j]-s[i]); 9 end; 10 11 procedure add(var app:longint; aa:longint); 12 begin 13 app:=((app mod p)+(aa mod p)) mod p; 14 end; 15 16 begin 17 readln(n); 18 for i:= 1 to n do 19 begin 20 readln(a[i]); 21 s[i]:=s[i-1]+a[i]; 22 end; 23 24 f[0]:=1; 25 for i:= 1 to n do 26 for j:= 0 to i-1 do 27 if sum(j,i)>=0 then add(f[i],f[j]); 28 29 writeln(f[n]); 30 end.
于是我们要优化哇,对状态转移方程移项可得:
可见求f[i]时,如果前面的sum[j-1]小于等于sum[i]就把他对应的f[j]加到f[i]里
所以我们可以用树状数组维护,用sum作为tree的下标表示tree[b]表示当前情况下sum=b的对应的分组种数
因为sum=b可能会超级大,于是我们可以离散
离散,就是计算出第i个前缀和的排第几小存在f[i]里面,双字段qsort实现,因为要保证后面的循环查询更新按照顺序
但是要注意边界和负数情况,我们首先将Sum=0加入同时更新边界即 add(f[1],1)
然后循环不断查询tree[1..sum[i]]的区间和便得到了此时的f[i]存到ans, 并更新
那么时间复杂度大概是
1 program w; 2 const 3 p=1000000009; 4 5 var 6 n,i,ans:longint; 7 sum,a,rk,f,tree:array[0..100000] of longint; 8 9 function lowbit(app:longint):longint; 10 begin 11 exit(app and -app); 12 end; 13 14 procedure add(ii,x:longint); 15 begin 16 while ii<=n do 17 begin 18 tree[ii]:=(tree[ii]+x) mod p; 19 ii:=ii+lowbit(ii); 20 end; 21 end; 22 23 function get(aa:longint):longint; 24 begin 25 get:=0; 26 while aa>0 do 27 begin 28 get:=(get+tree[aa]) mod p; 29 aa:=aa-lowbit(aa); 30 end; 31 end; 32 33 procedure qsort(l,r: longint); 34 //注意一定要双字段 35 var 36 i,j,x,y,z: longint; 37 begin 38 i:=l; j:=r; x:=sum[(l+r) div 2]; z:=rk[(l+r) div 2]; 39 repeat 40 while (sum[i]<x) or ((sum[i]=x) and (rk[i]<z)) do inc(i); 41 while (x<sum[j]) or ((sum[j]=x) and (rk[j]>z)) do dec(j); 42 if not(i>j) then 43 begin 44 y:=sum[i]; sum[i]:=sum[j]; sum[j]:=y; 45 y:=rk[i]; rk[i]:=rk[j]; rk[j]:=y; 46 inc(i); j:=j-1; 47 end; 48 until i>j; 49 if l<j then qsort(l,j); 50 if i<r then qsort(i,r); 51 end; 52 53 begin 54 readln(n); 55 for i:= 1 to n do 56 readln(a[i]); 57 58 n:=n+1; sum[1]:=0; rk[1]:=1; 59 for i:= 2 to n do 60 begin 61 sum[i]:=sum[i-1]+a[i-1]; 62 rk[i]:=i; 63 end; 64 65 qsort(1,n); 66 67 for i:= 1 to n do 68 f[rk[i]]:=i; 69 70 add(f[1],1); //处理边界 71 for i:= 2 to n do //循环到i ,得出来的ans便是f[i]的值 72 begin 73 ans:=get(f[i]); 74 add(f[i],ans); 75 end; 76 77 writeln(ans); 78 end.
转载于:https://www.cnblogs.com/bobble/p/6846922.html
luogu P2344 奶牛抗议 DP 树状数组 离散化相关推荐
- 树形DP+树状数组 HDU 5877 Weak Pair
1 //树形DP+树状数组 HDU 5877 Weak Pair 2 // 思路:用树状数组每次加k/a[i],每个节点ans+=Sum(a[i]) 表示每次加大于等于a[i]的值 3 // 这道题要 ...
- 小魂和他的数列(dp+树状数组优化)
链接:https://ac.nowcoder.com/acm/contest/3566/C 来源:牛客网 Sometimes, even if you know how something's goi ...
- 牛客多校1 - Infinite Tree(虚树+换根dp+树状数组)
题目链接:点击查看 题目大意:给出一个无穷个节点的树,对于每个大于 1 的点 i 来说,可以向点 i / minvid[ i ] 连边,这里的 mindiv[ x ] 表示的是 x 的最小质因数,现在 ...
- dp 树状数组 逆序元组
wmq的队伍 发布时间: 2017年4月9日 17:06 最后更新: 2017年4月9日 17:07 时间限制: 2000ms 内存限制: 512M 描述 交大上课需要打卡,于是在上课前的 ...
- BZOJ.4553.[HEOI2016TJOI2016]序列(DP 树状数组套线段树/二维线段树(MLE) 动态开点)
题目链接:BZOJ 洛谷 \(O(n^2)\)DP很好写,对于当前的i从之前满足条件的j中选一个最大值,\(dp[i]=d[j]+1\) for(int j=1; j<i; ++j)if(a[j ...
- HDU 2836 Traversal 简单DP + 树状数组
题意:给你一个序列,问相邻两数高度差绝对值小于等于H的子序列有多少个. dp[i]表示以i为结尾的子序列有多少,易知状态转移方程为:dp[i] = sum( dp[j] ) + 1;( abs( he ...
- Codeforces 1096F(dp + 树状数组)
题目链接 题意: 对于长度为$n$的排列,在已知一些位的前提下求逆序对的期望 思路: 将答案分为$3$部分 $1.$$-1$与$-1$之间对答案的贡献.由于逆序对考虑的是数字之间的大小关系,故假设$- ...
- 51nod 1680区间求和 (dp+树状数组/线段树)
不妨考虑已知一个区间[l,r]的k=1.k=2....k=r-l+1这些数的答案ans(只是这一个区间,不包含子区间) 那么如果加入一个新的数字a[i](i = r+1) 则新区间[l, i]的答案为 ...
- bzoj 2131: 免费的馅饼【dp+树状数组】
简单粗暴的dp应该是把馅饼按时间排序然后设f[i]为i接到馅饼能获得的最大代价,转移是f[i]=max(f[j])+v[i],t[j]<=t[i],2t[i]-2t[j]>=abs(p[i ...
最新文章
- 2021 考研 基本常识
- kotlin 查找id_Kotlin程序查找等边三角形的区域
- 一步一步重写 CodeIgniter 框架 (8) —— 视图的嵌套输出与返回
- 三星公布三款新型车用芯片 向大众供应
- Linux下update和upgrade的区别
- python 工程结构加固_gb50367 2013免费下载|混凝土结构加固设计规范GB50367-2013pdf高清电子版免费下载-东坡下载...
- windows10下破解开机密码
- 免费分享佳能ir c3320 c3330 c3325彩色复印机中文维修手册
- Ragel——基于有限状态机用于产生源码的编译器
- 如何快速裁剪pdf中的页面
- 怎么使用7zip进行分批压缩_7z解压软件(7-zip)分卷压缩怎么做?
- 逆水寒7.25服务器维护,逆水寒7月4日更新维护公告 角色交易功能上线
- 弘辽科技:端午节拼多多有优惠吗?力度如何?
- excel计算二元线性回归_分享一个用用Excel做回归分析
- 前端学习路线(简洁清晰,直击学习途径)
- 《游戏学习》纯JS中国象棋人机对战html游戏源码
- itms-services php,APP发布系统 ipa文件上传和下载 itms-service协议
- 移动端SEO技术难但机会大 优化要点总结
- 信息与通信工程考研参考(含第四轮学科评估结果与历年国家线)
- 程序员考公指南:逃离996的最强出路,拒绝秃顶的最佳方法
热门文章
- 为什么爬虫都用python_python为什么叫网络爬虫
- hutool获取5天前的日期_连载|日 产 物 流 管 理 方 式(5)
- java 反射 构造器_Java之类的构造器(反射)
- python opencv录制视频_Python-OpenCV 处理视频(一)(二): 输入输出 视频处理
- R中统计假设检验总结
- html重复div绘制,[DIV+CSS]绘制2重交叉表_html/css_WEB-ITnose
- 在计算机应用领域中媒体是指,在计算机中,媒体是指什么
- 怎样开图纸便宜_一步一步教你如何看懂工程图纸,值得收藏!
- 【备忘】二叉树遍历的迭代实现
- 系统学习机器学习之增强学习(五)--马尔可夫决策过程策略TD求解(SARSA)