• POJ 3468 线段树+状压


    题意:给你n个数,有对区间的加减操作,问某个区间的和是多少。
    思路:状压+线段树(要用lazy标记,否则会TLE)

    //By SiriusRen
    #include <cstdio>
    #include <cstring>
    #define N 100001
    using namespace std;
    long long tree[N*4],lazy[N*4];
    int xx,yy,zz,n,q;
    char jy;
    void push_down(int pos,int num){
        lazy[pos*2]+=lazy[pos],lazy[pos*2+1]+=lazy[pos];
        tree[pos*2]+=(num-num/2)*lazy[pos],tree[pos*2+1]+=(num/2)*lazy[pos];
        lazy[pos]=0;
    }
    void build(int l,int r,int pos){
        if(l==r){scanf("%lld",&tree[pos]);return;}
        int mid=(l+r)/2;
        build(l,mid,pos*2),build(mid+1,r,pos*2+1);
        tree[pos]=tree[pos*2]+tree[pos*2+1];
    }
    void add(int l,int r,int pos){
        if(l>=xx&&r<=yy){lazy[pos]+=zz;tree[pos]+=(long long)(r-l+1)*zz;return;}
        if(lazy[pos])push_down(pos,r-l+1);
        int mid=(l+r)/2;
        if(mid>=xx)add(l,mid,pos*2);
        if(mid<yy)add(mid+1,r,pos*2+1);
        tree[pos]=tree[pos*2]+tree[pos*2+1];
    }
    long long query(int l,int r,int pos){
        if(l>=xx&&r<=yy)return tree[pos];
        if(lazy[pos])push_down(pos,r-l+1);
        int mid=(l+r)/2;
        if(mid<xx)return query(mid+1,r,pos*2+1);
        else if(mid>=yy)return query(l,mid,pos*2);
        else return query(l,mid,pos*2)+query(mid+1,r,pos*2+1);
    }
    int main(){
        scanf("%d%d",&n,&q);
        build(1,n,1);
        while(q--){
            scanf("
    %c%d%d",&jy,&xx,&yy);
            if(jy=='C')scanf("%d",&zz),add(1,n,1);
            else printf("%lld
    ",query(1,n,1));
        }
    }

    这里写图片描述

  • 相关阅读:
    第十二周作业
    第十二周上机练习
    第十一周作业
    第十一周上机练习
    第十周上机作业
    第九周上机练习
    第八周作业
    软件测试第一次作业
    Jsp第二次作业
    JSP第一次作业
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6532436.html
Copyright © 2020-2023  润新知