• zoj 2706 线段树


    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1706

    trick:关于正数和负数的整除问题,正数整除是自动向下取整的,但负数是向上取整的
    即13/3=4.3 ->4 但-13/3=-4.3 ->-4

    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <queue>
    #include <vector>
    
    #define maxn 32500
    #define maxe 11000
    #define INF  0x3f3f3f
    #define lson l,mid,u<<1
    #define rson mid+1,r,u<<1|1
    #define ll_int long long int
    using namespace std;
    
    ll_int seg[maxn<<2];
    ll_int pau[maxn<<2];
    //bool   flag[maxn<<2];
    ll_int initsum;
    void PushUp(int u){
        seg[u] = seg[u<<1] + seg[u<<1|1];
    }
    void PushDown(int l,int r,int u){
        if(pau[u]){
            int mid = (l + r)/2;
            pau[u<<1] = pau[u<<1|1] = pau[u];
            seg[u<<1] = (ll_int)(mid - l + 1) * pau[u];
            seg[u<<1|1] = (ll_int)(r - mid) * pau[u];
            pau[u] = 0;
        }
    }
    void build(int l,int r,int u){
        seg[u] = 0;
        pau[u] = 0;
        if(l == r){
            scanf("%lld",&seg[u]); 
            initsum += seg[u];
            return;
        }
        int mid = (l + r)/2;
        build(lson);
        build(rson);
        PushUp(u);
    }
    
    void Update(int L,int R,int num,int l,int r,int u){
        if(L <= l && r <= R){
            pau[u] = num;
            seg[u] = (ll_int)(r - l + 1)* num;
            return;
        }
        PushDown(l,r,u);
        int mid = (l + r)/2;
        if(L <= mid)       Update(L,R,num,lson);
        if(R >  mid)       Update(L,R,num,rson);
        PushUp(u);  //要记住啊 
    }
    
    ll_int Query(int L,int R,int l,int r,int u){
        if(L <= l && r <= R){
            return seg[u];
        }
        PushDown(l,r,u); 
        int mid = (l + r)/2;
        ll_int ret = 0;
        if(L <= mid)  ret += Query(L,R,lson);
        if(R >  mid)  ret += Query(L,R,rson);
        return ret;
    }
    void print(int l,int r,int u){
        if(l == r){
            if(l == 1) printf("%lld",seg[u]);
            else       printf(" %lld",seg[u]);
            return;
        } 
        PushDown(l,r,u);
        int mid = (l + r)/2;
        print(lson);
        print(rson);
    }
    int main(){
    //    freopen("input.txt","r",stdin);
        int n,m;
        while(scanf("%d%d",&n,&m) == 2){
            initsum = 0;
            build(1,n,1);
            for(int i=1;i<=m;i++){
                int a,b;
                scanf("%d%d",&a,&b);
                
                ll_int sum = Query(a,b,1,n,1);
                int ave = sum/(b-a+1);
                
                if(sum > 0 && seg[1] <= initsum){  //为正的UP;
                    if(sum % (b-a+1)) ave++;
                }
                else if(sum < 0 && seg[1] > initsum){ //为负的down; 
                    if(sum % (b-a+1)) ave--;
                }
                
                Update(a,b,ave,1,n,1);
            }
            print(1,n,1);
            printf("
    
    ");
        } 
    }
    View Code
  • 相关阅读:
    mycat 1.6.6.1 distinct报错问题
    linux下Tomcat+OpenSSL配置单向&双向认证(自制证书)
    Too many open files错误与解决方法
    Tomcat类加载机制触发的Too many open files问题分析(转)
    spring boot 自签发https证书
    redis集群如何解决重启不了的问题
    centos7 docker 安装 zookeeper 3.4.13 集群
    centos7用docker安装kafka
    心怀感恩
    不使用if switch 各种大于 小于 判断2个数的大小
  • 原文地址:https://www.cnblogs.com/acmdeweilai/p/3237376.html
Copyright © 2020-2023  润新知