【题解】

  我们可以轻松想到朴素的状态转移方程,但直接这样做是n^2的。所以我们考虑采用树状数组优化。写法跟求逆序对很相似,即对前缀和离散化之后开一个权值树状数组,每次f[i]+=query(sum[i]),再把f[i]加入到sum[i]位置上。这样可以保证每次f[i]加上的是在它前面的、sum小于它的位置的f值。

  

 #include<cstdio>
#include<algorithm>
#define N 200010
#define rg register
#define Mod (1000000009)
using namespace std;
int n,m,f[N];
long long a[N],b[N],t[N];
inline int read(){
int k=,f=; char c=getchar();
while(c<''||c>'')c=='-'&&(f=-),c=getchar();
while(''<=c&&c<='')k=k*+c-'',c=getchar();
return k*f;
}
inline void add(int x,int y){
for(;x<=n+&&x>;x+=(x&-x)){t[x]+=y; t[x]%=Mod;}
}
inline int query(int x){
int ret=; for(;x;x-=x&-x){ret+=t[x]; ret%=Mod;} return ret%Mod;
}
int main(){
n=read();
for(rg int i=;i<=n;i++) a[i]=read()+a[i-],b[i]=a[i]; a[]=b[]=;
sort(b,b++n); int n2=unique(b,b++n)-b-;
for(rg int i=;i<=n;i++) a[i]=lower_bound(b,b++n2,a[i])-b+;
// for(rg int i=0;i<=n;i++) printf("%lld ",a[i]); puts("");
add(a[],f[]=);
for(rg int i=;i<=n;i++){
f[i]+=query(a[i]); f[i]%=Mod;
add(a[i],f[i]);
}
printf("%d\n",f[n]%Mod);
return ;
}

最新文章

  1. Azure SQL Database (20) 使用SQL Server 2016 Upgrade Advisor
  2. aischool 倒计时VIEW封装
  3. 安装ss
  4. Android——GridView(网格视图)相关知识总结贴
  5. 【FE前端学习】第二阶段任务-基础
  6. Spring 依赖注入,在Main方法中取得Spring控制的实例
  7. Netsharp FAQ
  8. awk 统计数据在文件中的出现次数
  9. Castle ActiveRecord配置中需要注意的地方
  10. Bootstrap 响应式瀑布流 (使用wookmark)
  11. 使用CountDownLatch和CyclicBarrier处理并发线程
  12. CentOS6.8通过yum安装MySQL5.7
  13. JSP之JSTL_functions
  14. Kafka笔记8(管理Kafka)
  15. filter 实现登录状态控制
  16. Solr中的q与fq参数的区别
  17. 关于DE2-115 FPGA开发板无法烧写程序的解决方法
  18. 用Qemu模拟vexpress-a9 (七) --- 嵌入式设备上安装telnet服务
  19. oracle12c创建用户和表空间出现的问题
  20. 利用atimicInteger cas的特性实现一个锁

热门文章

  1. IntelliJ IDEA 缓存和索引介绍
  2. 26.Extjs 部门列表信息展示页面
  3. 21. Ext中表格自适应高度
  4. 使用WinSXS进行系统盘瘦身Windows 7/2008/10/2012不断变大的C盘(Windows 更新清理)
  5. Android网络相关代码
  6. E20171229-hm
  7. bzoj 1638: [Usaco2007 Mar]Cow Traffic 奶牛交通【记忆化搜索】
  8. Linux 常规操作指南
  9. CentOS6.5磁盘分区和挂载操作记录
  10. 312 Burst Balloons 戳气球