【洛谷】2344 奶牛抗议 DP+树状数组

30 篇文章 0 订阅
22 篇文章 0 订阅

题目传送门

这是一道普及组的题目……不要拦着我,我要跳楼……

首先我们可以轻松写出状态转移方程:f[i]=Σf[j] (j<=i&&s[j]<=s[i],其中s表示前缀和)

这个DP的时间复杂度是O(n^2)的,显然过不了这题。

然后我们就考虑有没有一种数据结构可以统计一个限度内的前缀和,显然树状数组满足了我们的要求。

于是这题就A掉啦……

p.s.这题的权值可能较大,记得在对权值离散化一下。

再次p.s.记得考虑1~i这些元素分成一段的可能。

附上AC代码:

#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;

const int N=1e5+10,p=1e9+9;
struct note{
	int w,wz;
	bool operator < (const note &lyf) const {return w==lyf.w?wz<lyf.wz:w<lyf.w;}
}a[N];
int n,x,num[N],t[N],f[N];

inline char nc(void){
	static char ch[100010],*p1=ch,*p2=ch;
	return p1==p2&&(p2=(p1=ch)+fread(ch,1,100010,stdin),p1==p2)?EOF:*p1++;
}

inline void read(int &a){
	static char c=nc();int f=1;
	for (;!isdigit(c);c=nc()) if (c=='-') f=-1;
	for (a=0;isdigit(c);a=(a<<3)+(a<<1)+c-'0',c=nc());
	a*=f;return;
}

#define lowbit(x) (x&-x)
inline int get(int x){int sum=0;for (int i=x; i; i-=lowbit(i)) sum=(sum+t[i])%p;return sum;}
inline void add(int x,int y){for (int i=x; i<=n; i+=lowbit(i)) t[i]=(t[i]+y)%p;return;}

int main(void){
	read(n);
	for (int i=1; i<=n; ++i) read(x),a[i]=(note){a[i-1].w+x,i};
	sort(a+1,a+1+n);
	for (int i=1; i<=n; ++i) num[a[i].wz]=i;
	for (int i=1; i<=n; ++i) add(num[i],f[i]=((a[num[i]].w>=0)+get(num[i]))%p);
	printf("%d\n",f[n]);
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值