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 的余数

输入输出样例

输入样例#1:

4
2
3
-3
1

输出样例#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 树状数组 离散化相关推荐

  1. 树形DP+树状数组 HDU 5877 Weak Pair

    1 //树形DP+树状数组 HDU 5877 Weak Pair 2 // 思路:用树状数组每次加k/a[i],每个节点ans+=Sum(a[i]) 表示每次加大于等于a[i]的值 3 // 这道题要 ...

  2. 小魂和他的数列(dp+树状数组优化)

    链接:https://ac.nowcoder.com/acm/contest/3566/C 来源:牛客网 Sometimes, even if you know how something's goi ...

  3. 牛客多校1 - Infinite Tree(虚树+换根dp+树状数组)

    题目链接:点击查看 题目大意:给出一个无穷个节点的树,对于每个大于 1 的点 i 来说,可以向点 i / minvid[ i ] 连边,这里的 mindiv[ x ] 表示的是 x 的最小质因数,现在 ...

  4. dp 树状数组 逆序元组

    wmq的队伍 发布时间: 2017年4月9日 17:06   最后更新: 2017年4月9日 17:07   时间限制: 2000ms   内存限制: 512M 描述 交大上课需要打卡,于是在上课前的 ...

  5. 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 ...

  6. HDU 2836 Traversal 简单DP + 树状数组

    题意:给你一个序列,问相邻两数高度差绝对值小于等于H的子序列有多少个. dp[i]表示以i为结尾的子序列有多少,易知状态转移方程为:dp[i] = sum( dp[j] ) + 1;( abs( he ...

  7. Codeforces 1096F(dp + 树状数组)

    题目链接 题意: 对于长度为$n$的排列,在已知一些位的前提下求逆序对的期望 思路: 将答案分为$3$部分 $1.$$-1$与$-1$之间对答案的贡献.由于逆序对考虑的是数字之间的大小关系,故假设$- ...

  8. 51nod 1680区间求和 (dp+树状数组/线段树)

    不妨考虑已知一个区间[l,r]的k=1.k=2....k=r-l+1这些数的答案ans(只是这一个区间,不包含子区间) 那么如果加入一个新的数字a[i](i = r+1) 则新区间[l, i]的答案为 ...

  9. 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 ...

最新文章

  1. 2021 考研 基本常识
  2. kotlin 查找id_Kotlin程序查找等边三角形的区域
  3. 一步一步重写 CodeIgniter 框架 (8) —— 视图的嵌套输出与返回
  4. 三星公布三款新型车用芯片 向大众供应
  5. Linux下update和upgrade的区别
  6. python 工程结构加固_gb50367 2013免费下载|混凝土结构加固设计规范GB50367-2013pdf高清电子版免费下载-东坡下载...
  7. windows10下破解开机密码
  8. 免费分享佳能ir c3320 c3330 c3325彩色复印机中文维修手册
  9. Ragel——基于有限状态机用于产生源码的编译器
  10. 如何快速裁剪pdf中的页面
  11. 怎么使用7zip进行分批压缩_7z解压软件(7-zip)分卷压缩怎么做?
  12. 逆水寒7.25服务器维护,逆水寒7月4日更新维护公告 角色交易功能上线
  13. 弘辽科技:端午节拼多多有优惠吗?力度如何?
  14. excel计算二元线性回归_分享一个用用Excel做回归分析
  15. 前端学习路线(简洁清晰,直击学习途径)
  16. 《游戏学习》纯JS中国象棋人机对战html游戏源码
  17. itms-services php,APP发布系统 ipa文件上传和下载 itms-service协议
  18. 移动端SEO技术难但机会大 优化要点总结
  19. 信息与通信工程考研参考(含第四轮学科评估结果与历年国家线)
  20. 程序员考公指南:逃离996的最强出路,拒绝秃顶的最佳方法

热门文章

  1. 为什么爬虫都用python_python为什么叫网络爬虫
  2. hutool获取5天前的日期_连载|日 产 物 流 管 理 方 式(5)
  3. java 反射 构造器_Java之类的构造器(反射)
  4. python opencv录制视频_Python-OpenCV 处理视频(一)(二): 输入输出 视频处理
  5. R中统计假设检验总结
  6. html重复div绘制,[DIV+CSS]绘制2重交叉表_html/css_WEB-ITnose
  7. 在计算机应用领域中媒体是指,在计算机中,媒体是指什么
  8. 怎样开图纸便宜_一步一步教你如何看懂工程图纸,值得收藏!
  9. 【备忘】二叉树遍历的迭代实现
  10. 系统学习机器学习之增强学习(五)--马尔可夫决策过程策略TD求解(SARSA)