hdu 4107 Gangster(线段树)

 

线段树记录区间最大最小值, 当最大值小于p时, 整个区间都可以加上c, 当最小值大于p时, 区间要加上2*c,

否则不更新

 

时间卡的太紧,需要手写输入

 

tomyself

{

刚开始还记录了区间和,其实用最大值或最小值就可以求得数列

文件输入又忘了注释还wa了两次= =

数组要记得初始化

}

#include
   
   
    
    
#include
    
    
     
     
#include
     
     
      
      
#include
      
      
       
       
#include
       
       
         #include 
        
          #include 
         
           #include 
          
            #include 
            #include 
            
              using namespace std; #define inf 0x3f3f3f3f #define eps 1e-8 #define maxn 200009 #define maxe 800009 #define mod 1000007 #define FOR(i,s,t) for(int i = s; i < t; i++ ) #define LL long long int #define ULL unsigned long long #define pii pair 
             
               #define lson id << 1 , l , m #define rson id << 1 | 1 , m + 1 , r int Max[maxe], Min[maxe], add[maxe]; int n, m, p, a, b, c; void up ( int id ) { int ls = id << 1, rs = ls|1; //sum[id] = sum[ls] + sum[rs]; Max[id] = max( Max[ls], Max[rs] ); Min[id] = min( Min[ls], Min[rs] ); } void down ( int id, int len ) { int ls = id << 1, rs = ls | 1; add[ls] += add[id]; add[rs] += add[id]; //sum[ls] += ( len - (len>>1) ) * add[id]; //sum[rs] += ( len>>1 ) * add[id]; Max[ls] += add[id], Min[ls] += add[id]; Max[rs] += add[id], Min[rs] += add[id]; add[id] = 0; } void update ( int id, int l, int r, int ll, int rr ) { if( ll <= l && r <= rr ) { if( Max[id] < p ) { //sum[id] += ( r - l + 1 ) * c; Max[id] += c, Min[id] += c; add[id] += c; return ; } if( Min[id] >= p ) { //sum[id] += ( r - l + 1 ) * c * 2; Max[id] += 2*c, Min[id] += 2*c; add[id] += 2*c; return; } } if( add[id] ) down( id, r - l + 1 ); int m = ( l+r ) >> 1; if( ll <= m ) update( lson, ll, rr ); if( rr > m ) update( rson, ll, rr ); up( id ); } void solve ( int id, int l, int r ) { if( l == r ) { if( l != 1 ) putchar( ' ' ); printf("%d",Max[id]); return; } if( add[id] ) down( id, r - l + 1 ); int m = ( l + r ) >> 1; solve ( lson ); solve ( rson ); } inline int scan () { int ret = 0; char c; while( ( c = getchar() ) && ! ( '0' <= c && c <= '9' ) ); ret = c-'0'; while( ( c = getchar() ) && ( '0' <= c && c <= '9' ) ) ret = ret*10 + c-'0'; return ret; } int main () { //freopen( "data.txt", "r", stdin ); while( scanf("%d%d%d", &n, &m, &p )!= EOF ) { //memset( sum, 0, sizeof( sum ) ); memset( Max, 0, sizeof( Max ) ); memset( Min, 0, sizeof( Min ) ); memset( add, 0, sizeof( add ) ); while( m-- ) { a = scan(), b = scan(), c = scan(); update( 1, 1, n, a, b); } solve (1, 1, n); puts( "" ); } return 0; } 
              
             
           
          
         
       
      
      
     
     
    
    
   
   

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值