Bzoj5209[Tjoi2012]防御:姿势题

首先这题现在在BZOJ上是没数据的,你可以选择python2B获得AC,也可以去洛谷上交。
选择第一个选项的现在可以不用看了......

关于这题的题意,击破的一次攻击即使溢出也不双倍,否则你过不了样例。
然后考虑每个防御只会被击破一次,那么我们可以像HEOI2017相逢是问候那样用一个线段树去维护是否被击破。
然而那个题每次暴力push到底就行了,但这个题如果这样做,会发现在push时可能没有任何防御被击破,复杂度不对......
考虑用奇怪的办法保证存在防御被击破,我们维护区间的min,如果这个区间的min<=当前攻击值,则我们有必要在这个区间push到底。
然后就是实现的问题,自己YY一下就好了,我是用一个单独的函数去实现的push到底这个操作......
注意各种分类讨论......
别问我为什么刷这种水题......
今天好不容易不考试写神题也写不动啊......

我的代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define debug cout
 6 typedef long long int lli;
 7 using namespace std;
 8 const int maxn=1e5+1e2;
 9 const int mod=1e9+9;
10 const int inf=0x3f3f3f3f;
11 
12 int in[maxn<<3];
13 int l[maxn<<3],r[maxn<<3],lson[maxn<<3],rson[maxn<<3],siz[maxn<<3],full[maxn<<3],cnt; // size means number needs to be doubled .
14 lli sum[maxn<<3],miv[maxn<<3],lazy[maxn<<3]; // lazy means attack not pushsed ( not doubled ) .
15 
16 inline void build(int pos,int ll,int rr) {
17     l[pos] = ll , r[pos] = rr , full[pos] = rr - ll + 1;
18     if( ll == rr ) {
19         miv[pos] = in[ll];
20         return;
21     } const int mid = ( ll + rr ) >> 1;
22     build(lson[pos]=++cnt,ll,mid) , build(rson[pos]=++cnt,mid+1,rr);
23     miv[pos] = min( miv[lson[pos]] , miv[rson[pos]] );
24 }
25 inline void apply(int pos,lli x) {
26     lazy[pos] += x , sum[pos] += ( full[pos] + siz[pos] ) * x;
27     if( miv[pos] != inf ) miv[pos] -= x;
28 }
29 inline void push(int pos) {
30     if( !lazy[pos] ) return;
31     apply(lson[pos],lazy[pos]) , apply(rson[pos],lazy[pos]) , lazy[pos] = 0;
32 }
33 inline void maintain(int pos) {
34     siz[pos] = siz[lson[pos]] + siz[rson[pos]] ,
35     sum[pos] = sum[lson[pos]] + sum[rson[pos]] ,
36     miv[pos] = min( miv[lson[pos]] , miv[rson[pos]] );
37 }
38 inline void chain(int pos,lli x) {
39     if( x < miv[pos] ) { // nothing will be destoryed .
40         apply(pos,x);
41         return;
42     }
43     if( l[pos] == r[pos] ) { // assert x <= miv[pos] .
44         sum[pos] += x , siz[pos] = 1 , miv[pos] = inf;
45     } else { // push lazy at the same time .
46         chain(lson[pos],x+lazy[pos]) , chain(rson[pos],x+lazy[pos]) , lazy[pos] = 0;
47         maintain(pos);
48     }
49 }
50 inline void update(int pos,int ll,int rr,lli x) {
51     if( r[pos] < ll || rr < l[pos] ) return;
52     if( ll <= l[pos] && r[pos] <= rr ) return chain(pos,x);
53     push(pos);
54     update(lson[pos],ll,rr,x) , update(rson[pos],ll,rr,x);
55     maintain(pos);
56 }
57 inline lli query(int pos,int ll,int rr) {
58     if( r[pos] < ll || rr < l[pos] ) return 0;
59     if( ll <= l[pos] && r[pos] <= rr ) return sum[pos];
60     push(pos);
61     return query(lson[pos],ll,rr) + query(rson[pos],ll,rr);
62 }
63 
64 int main() {
65     static int n,m;
66     static char o[10];
67     static lli ans;
68     scanf("%d%d",&n,&m);
69     for(int i=1;i<=n;i++) scanf("%d",in+i);
70     build(cnt=1,1,n);
71     for(int i=1,l,r,x;i<=m;i++) {
72         scanf("%s%d",o,&l);
73         if( *o == 'A' ) {
74             scanf("%d%d",&r,&x);
75             update(1,l,r,x);
76         } else if( *o == 'Q' ) {
77             ( ans += query(1,l,l) % mod  ) %= mod;
78         }
79     }
80     printf("%lld\n",ans);
81     return 0;
82 }
View Code


最后给大家送上数据和对拍器,用lemon的格式打包的。

链接: https://pan.baidu.com/s/1n518YAQFYH02hi2ZNB41EQ 密码: ahym

 

posted @ 2018-03-19 21:04  Cmd2001  阅读(227)  评论(0编辑  收藏  举报