zoukankan      html  css  js  c++  java
  • 线段树动态开点区间加区间求和

    线段树动态开点区间加区间求和


    题目来源:

    陕西师范大学第七届程序设计竞赛网络同步赛 H. 万恶的柯怡

    思想:

    保证叶子节点被完整的覆盖,需要开节点,就把左右儿子都开出来,其余和普通线段树一样。

    tips:

    用结构体内部函数,内存不足,(第一次遇见本地问题不严重)不明嚼栗???

    模板:

    #include <bits/stdc++.h>
    typedef long long ll;
    const int N = 4000010;
    using namespace std;
    struct node{
        ll sum,tag;int lson,rson;
    //    node(){}node(ll c,ll d,int e,int f){ ***memory limit error***
    //        sum=c;tag=d;lson=e;rson=f;
    //    }
    }T[N];
    int cnt;
    void newnode(int &x,ll sum) {
        x = ++cnt;
        T[x].sum = sum;
        T[x].lson = T[x].rson = -1;
        T[x].tag = 0;
    }
    void push_down(int p,ll l,ll r) {
        ll mid = (l+r) >> 1LL;
        if(T[p].tag) {
            if(T[p].lson==-1&&T[p].rson==-1){
                newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));
                newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));
                T[T[p].lson].tag += T[p].tag;
                T[T[p].rson].tag += T[p].tag;
            }
            else {
                T[T[p].lson].tag += T[p].tag;
                T[T[p].rson].tag += T[p].tag;
                T[T[p].lson].sum += T[p].tag*(mid-l+1LL);
                T[T[p].rson].sum += T[p].tag*(r-mid);
            }
            T[p].tag = 0;
        }
    }
    ll ask(int p,ll L,ll R,ll l,ll r) {
        if(L<=l&&r<=R) return T[p].sum;
        push_down(p,l,r);
        ll mid = (l+r)>>1LL;
        if(mid>=R) {
            if(T[p].lson==-1) newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));
            if(T[p].rson==-1) newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));
            return ask(T[p].lson,L,R,l,mid);
        }
        else if(mid < L) {
            if(T[p].lson==-1) newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));
            if(T[p].rson==-1) newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));
            return ask(T[p].rson,L,R,mid+1LL,r);
        }
        else {
            if(T[p].lson==-1) newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));
            if(T[p].rson==-1) newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));
            return ask(T[p].lson,L,mid,l,mid)+ask(T[p].rson,mid+1LL,R,mid+1LL,r);
        }
    }
    void push_up(int p) {
        T[p].sum = (T[p].lson!=-1)*T[T[p].lson].sum + (T[p].rson!=-1)*T[T[p].rson].sum;
    }
    
    void add(int p,ll L,ll R,ll l,ll r,ll x) {
        if(L<=l&&r<=R) {
            T[p].tag += x;
            T[p].sum += (r-l+1LL)*x;
            return;
        }
        push_down(p,l,r);
        ll mid = (l+r)>>1LL;
        if(mid>=R) {
            if(T[p].lson==-1) newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));
            if(T[p].rson==-1) newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));
            add(T[p].lson,L,R,l,mid,x);
        }
        else if(mid < L) {
            if(T[p].lson==-1) newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));
            if(T[p].rson==-1) newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));
            add(T[p].rson,L,R,mid+1LL,r,x);
        }
        else {
            if(T[p].lson==-1) newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));
            if(T[p].rson==-1) newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));
            add(T[p].lson,L,mid,l,mid,x),add(T[p].rson,mid+1LL,R,mid+1LL,r,x);
        }
        push_up(p);
    }
    
    int main() {
        int q;
        scanf("%d",&q);
        cnt = 0;
        int rt = ++cnt;int K=0;
        ll res = 0;
        T[rt].sum = 0;T[rt].lson=T[rt].rson = -1;T[rt].tag = 0;
        while(q--) {int opt;ll L,R,x;
            scanf("%d",&opt);
            if(opt) {
                scanf("%lld%lld",&L,&R);
                printf("%lld
    ",ask(rt,L,R,0,1000000000LL));
            }
            else {
                scanf("%lld%lld%lld",&L,&R,&x);
                add(rt,L,R,0,1000000000LL,x);
            }
        }
        return 0;
    }
    
    

    H. 万恶的柯怡

    #include <bits/stdc++.h>
    typedef long long ll;
    const int N = 4000010;
    using namespace std;
    struct node{
        ll sum,tag;int lson,rson;
    }T[N];
    int cnt;
    void newnode(int &x,ll sum) {
        x = ++cnt;
        T[x].sum = sum;
        T[x].lson = T[x].rson = -1;
        T[x].tag = 0;
    }
    void push_down(int p,ll l,ll r) {
        ll mid = (l+r) >> 1LL;
        if(T[p].tag) {
            if(T[p].lson==-1&&T[p].rson==-1){
                newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));
                newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));
                T[T[p].lson].tag += T[p].tag;
                T[T[p].rson].tag += T[p].tag;
            }
            else {
                T[T[p].lson].tag += T[p].tag;
                T[T[p].rson].tag += T[p].tag;
                T[T[p].lson].sum += T[p].tag*(mid-l+1LL);
                T[T[p].rson].sum += T[p].tag*(r-mid);
            }
            T[p].tag = 0;
        }
    }
    ll ask(int p,ll L,ll R,ll l,ll r) {
        if(L<=l&&r<=R) return T[p].sum;
        push_down(p,l,r);
        ll mid = (l+r)>>1LL;
        if(mid>=R) {
            if(T[p].lson==-1) newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));
            if(T[p].rson==-1) newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));
            return ask(T[p].lson,L,R,l,mid);
        }
        else if(mid < L) {
            if(T[p].lson==-1) newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));
            if(T[p].rson==-1) newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));
            return ask(T[p].rson,L,R,mid+1LL,r);
        }
        else {
            if(T[p].lson==-1) newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));
            if(T[p].rson==-1) newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));
            return ask(T[p].lson,L,mid,l,mid)+ask(T[p].rson,mid+1LL,R,mid+1LL,r);
        }
    }
    void push_up(int p) {
        T[p].sum = (T[p].lson!=-1)*T[T[p].lson].sum + (T[p].rson!=-1)*T[T[p].rson].sum;
    }
    
    void add(int p,ll L,ll R,ll l,ll r,ll x) {
        if(L<=l&&r<=R) {
            T[p].tag += x;
            T[p].sum += (r-l+1LL)*x;
            return;
        }
        push_down(p,l,r);
        ll mid = (l+r)>>1LL;
        if(mid>=R) {
            if(T[p].lson==-1) newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));
            if(T[p].rson==-1) newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));
            add(T[p].lson,L,R,l,mid,x);
        }
        else if(mid < L) {
            if(T[p].lson==-1) newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));
            if(T[p].rson==-1) newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));
            add(T[p].rson,L,R,mid+1LL,r,x);
        }
        else {
            if(T[p].lson==-1) newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));
            if(T[p].rson==-1) newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));
            add(T[p].lson,L,mid,l,mid,x),add(T[p].rson,mid+1LL,R,mid+1LL,r,x);
        }
        push_up(p);
    }
    
    int main() {
        int TT;
        scanf("%d",&TT);
        while(TT--) {
            int q;
            scanf("%d",&q);
            cnt = 0;
            int rt = ++cnt;int K=0;
            ll res = 0;
            T[rt].sum = 0;T[rt].lson=T[rt].rson = -1;T[rt].tag = 0;
            while(q--) {ll l,r,keyiL,keyiR,x;
                scanf("%lld %lld %lld %lld %lld",&l,&r,&x,&keyiL,&keyiR);
                l=l^res;r=r^res;keyiL=keyiL^res;keyiR=keyiR^res;
                if(l>r)swap(l,r);if(keyiL>keyiR)swap(keyiL,keyiR);
                add(rt,l,r,0,1000000000,x);
                res = ask(rt,keyiL,keyiR,0,1000000000);
                printf("%lld
    ",res);
                res %= 19980105;
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    使用JRadioButton 示例
    使用JTextArea示例
    python与c语言的区别以及python的小小基础
    Linux常用的服务器构建
    在VMware虚拟机软件中安装的Ubuntu虚拟机的窗口不能自动调整大小的解决办法
    Ubuntu 下环境搭建系列 —— 安装 Google Chrome
    Linux命令复习和练习_03
    Android hybrid App项目构建和部分基本开发问题
    Ionic Framework
    node.js代理设置
  • 原文地址:https://www.cnblogs.com/RRRR-wys/p/9324745.html
Copyright © 2011-2022 走看看