zoukankan      html  css  js  c++  java
  • poj 3468(线段树+lazy思想)

    题目链接:http://poj.org/problem?id=3468

    思路:如果直接去做,每次都更新到叶子节点,那必然会TLE,我们可以采用lazy的思想:没必要每次更新都更新到叶子节点,只要有一个合适的范围就用一个增量来记录它,当下一次询问时,如果这个范围正好合适询问的范围,就直接是这个节点的sum值加上这个区间长度*lnc,再加到总和上去,若这个节点的范围不适合所要查询的范围,那么就要查询它的子节点,这个时候再把增量传给她的子节点,并且清空父亲节点的增量,这样效率能大大提高。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 #define MAXN 100010
      7 typedef long long ll;
      8 
      9 struct Node{
     10     int L,R;
     11     ll lnc;//增量
     12     ll sum;
     13 }node[MAXN<<2];
     14 
     15 int N,Q;
     16 
     17 void Build(int L,int R,int rt)
     18 {
     19     if(L==R){
     20         node[rt].lnc=node[rt].sum=0;
     21         return ;
     22     }
     23     node[rt].lnc=node[rt].sum=0;
     24     int M=(L+R)>>1;
     25     Build(L,M,rt<<1);
     26     Build(M+1,R,(rt<<1)|1);
     27 }
     28 
     29 void Updata(int L,int R,int rt,int id,ll x)
     30 {
     31     if(L==id&&R==id){
     32         node[rt].sum=x;
     33         return ;
     34     }
     35     node[rt].sum+=x;
     36     int M=(L+R)>>1;
     37     if(id<=M){
     38         Updata(L,M,rt<<1,id,x);
     39     }else 
     40         Updata(M+1,R,(rt<<1)|1,id,x);
     41 }
     42 
     43 void Add_Updata(int L,int R,int rt,int l,int r,ll x)
     44 {
     45     if(l<=L&&R<=r){
     46         node[rt].lnc+=x;//若此节点所在区段被包含在要插入的区段中,就将插入值存在lnc中,return;
     47         return ;
     48     }else if(L<=l&&r<=R){
     49         node[rt].sum+=(r-l+1)*x;
     50     }else if(L>=l&&R>=r){
     51         node[rt].sum+=(r-L+1)*x;
     52     }else if(L<=l&&R<=r){
     53         node[rt].sum+=(R-l+1)*x;
     54     }
     55     int M=(L+R)>>1;
     56     if(r<=M){
     57         Add_Updata(L,M,rt<<1,l,r,x);
     58     }else if(l>M){
     59         Add_Updata(M+1,R,(rt<<1)|1,l,r,x);
     60     }else {
     61         Add_Updata(L,M,rt<<1,l,r,x);
     62         Add_Updata(M+1,R,(rt<<1)|1,l,r,x);
     63     }
     64 }
     65 
     66 ll sum;
     67 void Query(int L,int R,int rt,int l,int r)
     68 {
     69     if(l<=L&&R<=r){
     70         sum+=node[rt].sum+node[rt].lnc*(R-L+1);
     71         return ;
     72     }
     73     //若上面if条件不成立,则要询问它的子节点,此时增量要下传,并且要更新其本身的sum;
     74     node[rt<<1].lnc+=node[rt].lnc;
     75     node[(rt<<1)|1].lnc+=node[rt].lnc;
     76     node[rt].sum+=node[rt].lnc*(R-L+1);
     77     node[rt].lnc=0;
     78     int M=(L+R)>>1;
     79     if(r<=M){
     80         Query(L,M,rt<<1,l,r);
     81     }else if(l>M){
     82         Query(M+1,R,(rt<<1)|1,l,r);
     83     }else {
     84         Query(L,M,rt<<1,l,r);
     85         Query(M+1,R,(rt<<1)|1,l,r);
     86     }
     87 }
     88 
     89 int main()
     90 {
     91     int a,b,c;
     92     char str[11];
     93     scanf("%d%d",&N,&Q);
     94     Build(1,N,1);
     95     for(int i=1;i<=N;i++){
     96         scanf("%d",&a);
     97         Updata(1,N,1,i,(ll)a);
     98     }
     99     while(Q--){
    100         scanf("%s",str);
    101         if(str[0]=='Q'){
    102             scanf("%d%d",&a,&b);
    103             sum=0;
    104             Query(1,N,1,a,b);
    105             printf("%lld
    ",sum);
    106         }else {
    107             scanf("%d%d%d",&a,&b,&c);
    108             Add_Updata(1,N,1,a,b,(ll)c);
    109         }
    110     }
    111     return 0;
    112 }
    113  
    114 
    115     
    View Code
  • 相关阅读:
    LeetCode 252. Meeting Rooms
    LeetCode 161. One Edit Distance
    LeetCode 156. Binary Tree Upside Down
    LeetCode 173. Binary Search Tree Iterator
    LeetCode 285. Inorder Successor in BST
    LeetCode 305. Number of Islands II
    LeetCode 272. Closest Binary Search Tree Value II
    LeetCode 270. Closest Binary Search Tree Value
    LeetCode 329. Longest Increasing Path in a Matrix
    LintCode Subtree
  • 原文地址:https://www.cnblogs.com/wally/p/3184918.html
Copyright © 2011-2022 走看看