• POJ 3468 (线段树)


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

    You have N integers, A1A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

    Input

    The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
    The second line contains N numbers, the initial values of A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
    Each of the next Q lines represents an operation.
    "C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
    "Q a b" means querying the sum of AaAa+1, ... , Ab.

    Output

    You need to answer all Q commands in order. One answer in a line.

    Sample Input

    10 5
    1 2 3 4 5 6 7 8 9 10
    Q 4 4
    Q 1 10
    Q 2 4
    C 3 6 3
    Q 2 4
    Sample Output

    4
    55
    9
    15

    Hint

    The sums may exceed the range of 32-bit integers.
     
     
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<algorithm>
      6 #include<map>
      7 #include<set>
      8 #include<vector>
      9 using namespace std;
     10 #define ll long long
     11 const int inf=99999999;
     12 const int mod=1e9+7;
     13 const int maxn=100000+10;
     14 typedef struct 
     15 {
     16     int left;
     17     int right;
     18     ll int weight;
     19     ll int lan;
     20 } St;
     21 St tree[maxn<<2];
     22 int n,m;
     23 int a,b;
     24 ll int ans;
     25 ll int num; 
     26 inline void build_tree(int k,int left,int right)//建树 
     27 {
     28     tree[k].left=left;
     29     tree[k].right=right;
     30     if(left==right)
     31     {
     32         cin>>tree[k].weight;
     33         return ;
     34     }
     35     int mid=(left+right)>>1;
     36     build_tree(k<<1,left,mid);//左子树
     37     build_tree(k<<1|1,mid+1,right);//右子树
     38     tree[k].weight=tree[k<<1].weight+tree[k<<1|1].weight;//状态合并,该节点权重等于左子树加右子树权重 
     39 }
     40 inline void lan_down(int k)//树懒标记下传 
     41 {
     42     tree[k<<1].lan+=tree[k].lan;
     43     tree[k<<1|1].lan+=tree[k].lan;
     44     tree[k<<1].weight+=tree[k].lan*(tree[k<<1].right-tree[k<<1].left+1);
     45     tree[k<<1|1].weight+=tree[k].lan*(tree[k<<1|1].right-tree[k<<1|1].left+1);
     46     tree[k].lan=0;
     47 }
     48 inline void ask_point(int k)//单点查询 
     49 {
     50     if(tree[k].left==tree[k].right)
     51     {
     52         ans=tree[k].weight;
     53         return ;
     54     }
     55     if(tree[k].lan)
     56         lan_down(k);
     57     int mid=(tree[k].left+tree[k].right)>>1;
     58     if(a<=mid)//a表示单点询问位置
     59         ask_point(k<<1);//目标位置靠左,递归左孩子
     60     else
     61         ask_point(k<<1|1);//目标位置靠右,递归右孩子
     62 }
     63 inline void add_point(int k)//单点修改 
     64 {
     65     if(tree[k].left==tree[k].right)
     66     {
     67         tree[k].weight+=num;//单点增加num 
     68         return ;
     69     }
     70     if(tree[k].lan)//树懒标记下传 
     71         lan_down(k);
     72     int mid=(tree[k].left+tree[k].right)>>1;
     73     if(a<=mid)
     74         add_point(k<<1);
     75     else
     76         add_point(k<<1|1);
     77     tree[k].weight=tree[k<<1].weight+tree[k<<1|1].weight;//状态合并 
     78 }
     79 inline void ask_qujian(int k)//区间查询 
     80 {
     81     if(tree[k].left>=a&&tree[k].right<=b)//包含了left,right当前区间,全加上 
     82     {
     83         ans+=tree[k].weight;
     84         return ;
     85     }
     86     if(tree[k].lan)//树懒标记下传 
     87         lan_down(k);
     88     int mid=(tree[k].left+tree[k].right)>>1;
     89     if(a<=mid)//递归查询左子区间 
     90         ask_qujian(k<<1);
     91     if(b>mid)//递归查询右子区间
     92         ask_qujian(k<<1|1);
     93 }
     94 inline void add_qujian(int k)//区间修改 
     95 {
     96     if(tree[k].left>=a&&tree[k].right<=b)
     97     {
     98         tree[k].weight+=num*(tree[k].right-tree[k].left+1);
     99         tree[k].lan+=num;
    100         return ;
    101     }
    102     if(tree[k].lan)
    103         lan_down(k);
    104     int mid=(tree[k].left+tree[k].right)>>1;
    105     if(a<=mid)
    106         add_qujian(k<<1);
    107     if(b>mid)
    108         add_qujian(k<<1|1);
    109     tree[k].weight=tree[k<<1].weight+tree[k<<1|1].weight;//状态合并 
    110 }
    111 int main()
    112 {
    113     ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    114     cin>>n>>m; //n个节点,m个操作 
    115     build_tree(1,1,n);//建树
    116     char op;
    117     for(int i=0;i<m;i++)
    118     {
    119         cin>>op>>a>>b;
    120         if(op=='Q')
    121         {
    122             ans=0;
    123             ask_qujian(1);//区间查询
    124             cout<<ans<<endl;
    125         }
    126         else if(op=='C')
    127         {
    128             cin>>num;
    129             add_qujian(1);//区间修改 
    130         }
    131     }
    132     return 0;
    133 }
    大佬见笑,,
  • 相关阅读:
    Ext JS 6开发实例(三) :主界面设计
    Ext JS 6开发实例(二) :使用CMD创建应用程序
    文件夹或者文件比对工具 Beyond Compare
    LIS问题(DP解法)---poj1631(模板)
    hdoj Max Sum Plus Plus(DP)
    A* 算法详解
    hdoj1043 Eight(逆向BFS+打表+康拓展开)
    hdoj2612 Find a way (bfs)
    luoguP3366 [模板] 最小生成树
    luoguP1196(带权并查集)
  • 原文地址:https://www.cnblogs.com/xwl3109377858/p/10914202.html
Copyright © 2020-2023  润新知