P2344 奶牛抗议(二维偏序+$dp$(!树状数组$0$基准!))

${\color{cyan}{>>Question}}$

二维偏序$dp$

方程很简单

令$f[i]$表示到$i$的方案数

有$$f[i] = \sum f[j],\sum_{k = j+1}^i a[k] \geq 0$$

写成前缀和的形式便是$$f[i] = \sum f[j],sum[i]-sum[j]\geq 0$$

观察可知$i$由$j$转移来有两个条件

$1.$ $j < i$

$2.$ $sum[j] <= sum[i]$

那可把$i$看成$(i,sum[i])$的点,就成了一个二维偏序问题

可以离散化,也可以不离散化

离散化就离散$sum[i]$,$i$天然有序

不离散化就以$sum[i]$为第一关键字,$i$为第二关键字排序

外面都套个树状数组即可

但我太菜了,第一次处理树状数组$0$基准的情况($f[0] = 1$),犯了很多错才调出来,具体看代码吧

 

离散化版

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <queue>
 6 #define ll long long
 7 using namespace std; 
 8 
 9 template <typename T> void in(T &x) {
10     x = 0; T f = 1; char ch = getchar();
11     while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
12     while( isdigit(ch)) {x = 10 * x + ch - 48; ch = getchar();}
13     x *= f;
14 }
15 
16 template <typename T> void out(T x) {
17     if(x < 0) x = -x , putchar('-');
18     if(x > 9) out(x/10);
19     putchar(x%10 + 48);
20 }
21 //-------------------------------------------------------
22 
23 const int N = 1e5+7,mod = 1e9+9;
24 int n;
25 ll b[N],ans;
26 
27 struct node {
28     int pos;ll sum;
29 }p[N];
30 
31 struct map {
32     int pos;ll sum;
33     bool operator < (const map &x) const {
34         return sum == x.sum ? pos < x.pos : sum < x.sum;//sum < x.sum;
35     }
36 }a[N];
37 
38 void A(int pos,ll k) {
39     for(int i = pos;i <= n;i += i&-i) b[i] = (b[i]+k)%mod;
40 }
41 
42 ll Q(int pos) {
43     ll res = 0;
44     for(int i = pos;i;i -= i&-i) res = (res + b[i])%mod;
45     return res;
46 }
47 
48 int main() {
49     //freopen("0.in","r",stdin);
50     //freopen("my.out","w",stdout);
51     int i; ll x;
52     in(n);
53     a[0].pos = a[0].sum = 0;
54     for(i = 1;i <= n; ++i) p[i].pos = i,in(x),p[i].sum = p[i-1].sum + x,a[i].pos = i,a[i].sum = p[i].sum;
55     sort(a,a+n+1);//debug a[0]
56     p[a[0].pos].sum = 1; int _id = 1;
57     for(i = 1;i <= n; ++i) {
58         if(a[i].sum != a[i-1].sum) ++_id;//debug i-1越界 
59         p[a[i].pos].sum = _id;
60     }
61     //for(i = 1;i <= n; ++i) cout << p[i].sum << endl;
62     A(p[0].sum,1);
63     for(i = 1;i <= n; ++i) {
64         ans = Q(p[i].sum);
65         A(p[i].sum,ans);
66         if(i == n) out(ans);
67         //out(ans),putchar('\n');
68     }
69     //out(ans);
70     return 0;
71 }

 

不离散化版

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <queue>
 6 #define ll long long
 7 using namespace std; 
 8 
 9 template <typename T> void in(T &x) {
10     x = 0; T f = 1; char ch = getchar();
11     while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
12     while( isdigit(ch)) {x = 10 * x + ch - 48; ch = getchar();}
13     x *= f;
14 }
15 
16 template <typename T> void out(T x) {
17     if(x < 0) x = -x , putchar('-');
18     if(x > 9) out(x/10);
19     putchar(x%10 + 48);
20 }
21 //-------------------------------------------------------
22 
23 const int N = 1e5+7,mod = 1e9+9;
24 int n;
25 ll b[N],ans;
26 ll f[N];
27 
28 struct node {
29     int pos;ll sum;
30     bool operator < (const node &x) const {
31         return sum == x.sum ? pos < x.pos : sum < x.sum;
32     }
33 }p[N];
34 
35 void A(int pos,ll k) {
36     for(int i = pos;i <= n+1;i += i&-i) b[i] = (b[i]+k)%mod;//debug n+1 -> n
37 }
38 
39 ll Q(int pos) {
40     ll res = 0;
41     for(int i = pos;i;i -= i&-i) res = (res + b[i])%mod;
42     return res;
43 }
44 
45 int main() {
46     //freopen("0.in","r",stdin);
47     int i; ll x;
48     in(n);
49     p[0].pos = 1,p[0].sum = 0;
50     for(i = 1;i <= n; ++i) p[i].pos = i+1,in(x),p[i].sum = p[i-1].sum + x;
51     sort(p,p+n+1);
52     for(i = 0;i <= n; ++i) {
53         if(p[i].pos == 1) A(p[i].pos,1);
54         f[p[i].pos-1] = Q(p[i].pos);
55         ll x = f[p[i].pos-1];
56         //if(p[i].pos == 1) A(p[i].pos,1);//debug//debug 
57         if(p[i].pos == 1) continue;
58         A(p[i].pos,x);
59     }
60     out(f[n]);
61     //for(i = 1;i <= n; ++i) cout << f[i] << endl;
62     return 0;
63 }

 

谢谢各位看官老爷支持(づ ̄3 ̄)づ╭❤~

posted @ 2019-08-21 11:20  陈星卿  阅读(257)  评论(0编辑  收藏  举报