Bzoj5209[Tjoi2012]防御:姿势题
首先这题现在在BZOJ上是没数据的,你可以选择python2B获得AC,也可以去洛谷上交。
选择第一个选项的现在可以不用看了......
关于这题的题意,击破的一次攻击即使溢出也不双倍,否则你过不了样例。
然后考虑每个防御只会被击破一次,那么我们可以像HEOI2017相逢是问候那样用一个线段树去维护是否被击破。
然而那个题每次暴力push到底就行了,但这个题如果这样做,会发现在push时可能没有任何防御被击破,复杂度不对......
考虑用奇怪的办法保证存在防御被击破,我们维护区间的min,如果这个区间的min<=当前攻击值,则我们有必要在这个区间push到底。
然后就是实现的问题,自己YY一下就好了,我是用一个单独的函数去实现的push到底这个操作......
注意各种分类讨论......
别问我为什么刷这种水题......
今天好不容易不考试写神题也写不动啊......
我的代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
最后给大家送上数据和对拍器,用lemon的格式打包的。
链接: https://pan.baidu.com/s/1n518YAQFYH02hi2ZNB41EQ 密码: ahym