HDU 5166 segment tree

The enemy lineup
TimeLimit: 2000/1000 MS (the Java / Others) the MemoryLimit: 65536/32768 K (the Java / Others)
64-bit Integer-IO format:% I64d
Problem the Description
rival C Country A country's ongoing military exercises this time , so C Derek national spy chief and his men began to busy Tidy up. A country coastline arranged along a line of the N engineering camps, Derek and Tidy task is to monitor the activities of these engineers camps. As a result of some kind of advanced monitoring tools, so the number of engineers in each camp C crystal clear grasp States, the number of engineers in each camp are likely to occur change, may increase or decrease the number of staff, but they can not escape C monitor the country.
CIA to study enemy tactics exactly what exercises, so Derek Tidy to keep the report a certain period of continuous engineering camp a total of how many people, such as Derek asked: "Tidy, immediately report the first three camps to many people of a total of 10 camps ! "Tidy will immediately begin to calculate the total number of this paragraph and report. But the number of enemy camps often change, and Derek asked each segment is different, so every time a Tidy had to go to a number of camps, soon exhausted, Derek to calculate the speed of the Tidy increasingly dissatisfied: "! you a dead fat boy, considered so slow, I fire you" Tidy thought: "you do the math yourself, which is really a tiring job I wish you fire me too!! "In desperation, Tidy had to call a computer expert to help Windbreaker, Windbreaker, said:"! dead fat boy, do you usually called multi-point acm title and see multi-point arithmetic book, now tasted the bitter fruit of it "Tidy said:" I admitted the mistake ... "but Windbreaker has hung up the phone. Tidy very upset, so he really will count crash, the intelligent reader, you can write a program to help him finish the job? But if your program efficiency is not high enough, Tidy will still be scolded Derek's.
The Input
A first line integer T, T set of data expressed.
Data of the first line of each a positive integer N (N <= 50000), there are N represents the enemy camps engineer, the next positive integers with N, has the i ai positive integer representing the i-th ai start engineering camp personal (1 <= ai <= 50 ).
Next, each row having a command, command has four forms:
(. 1) ij of the Add, i, and j is a positive integer, denotes the i th camp increase personal j (j is not more than 30)
(2) Sub ij of, i and j is a positive integer, denotes the i th camps reduce j individuals (j does not exceed 30);
(. 3) Query ij of, i and j are positive integers, i <= j, presents to ask the total number of i-th to j-th camps;
(4) end indicates the end, the last command that appears in each set of data;
up to 40,000 commands each data
output
of the i-th group of data, first outputs "Case i:" and enter,
for each query Query output the total number of integer and a carriage return, indicating an inquiry segment, this number remains within int.
SampleInput
. 1
10
. 1. 5. 4. 3 2. 6. 7. 9 10. 8
Query. 3. 1
the Add. 3. 6
Query 2. 7
Sub 10 2
the Add. 6. 3
Query. 3 10
End
SampleOutput
Case. 1:
. 6
33 is
59

Meaning of the questions: computing a sub-intervals under conditions and increase or decrease the number of
ideas: tree line template title single point update interval query
PS: left and right sub-tree version I wrote not-bit computing

#include <stdio.h>
#include <algorithm>

using namespace std;

const int maxn=1e5+5;

struct node
{
    int l,r,ans;///左右端点 答案
} t[maxn*4];

void build(int v,int l, int r)/// v仅是代表你递归的方向 l ,r 是区间
{
    t[v].l=l;
    t[v].r=r;
    
    if(l==r)///递归到叶节点时赋值并回溯
    {
        scanf("%d",&t[v].ans);
        return ;
    }
    
    int mid=(l+r)/2;
    build(2*v,l,mid);///向左子树建树
    build(2*v+1,mid+1,r);///向右子树建树
    
    t[v].ans=t[v*2].ans+t[v*2+1].ans;///父节点的值 是左右子节点值之和
}

int query(int v,int l,int r)/// l,r是查询的区间
{
    if(t[v].l==l&&t[v].r==r)///当该节点的区间与所查询的相同 则返回答案
        return t[v].ans;
    int mid=(t[v].l+t[v].r)/2; /// 注意这里是从结点的左右端点开始递归
    if(r<=mid)///如果想找的区间右节点比mid值还要小 说明答案在左边  往左递归
        query(2*v,l,r);
    else
    {
        if(l>mid)
            query(2*v+1,l,r);
        else
            return query(v*2,l,mid)+query(v*2+1,mid+1,r); ///存在区间横跨的话我们需要
    }
}

void update(int v,int x,int y)///x是更新的点 y是更新所加减的值
{
    if(t[v].l==t[v].r)
    {
        t[v].ans+=y;
        return ;
    }
    int mid=(t[v].l+t[v].r)/2;
    
    if(x<=mid)
        update(2*v,x,y);
    else
        update(2*v+1,x,y);
        
    t[v].ans=t[v*2].ans+t[v*2+1].ans;
}

int main()
{
    int t,n,x,y;
    char str[15];
    scanf("%d",&t);
    for(int i=1; i<=t; i++)
    {
        printf("Case %d:\n",i);
        scanf("%d",&n);
        build(1,1,n);/// v从1开始  建立1~n的树
        while(1)
        {
            scanf("%s",str);
            if(str[0]=='E')
                break;
            scanf("%d%d",&x,&y);
            if(str[0]=='Q')
            {
                printf("%d\n",query(1,x,y));
            }
            else if(str[0]=='A')
            {
                update(1,x,y);
            }
            else if(str[0]=='S')
            {
                update(1,x,-y);
            }
        }
    }
    return 0;
}

tips: update and query recursively used in the range are used interval own node carried rather than function declaration in the function declaration in the end is that you want to find the
tree line can be used to solve a single point queries a single point update interval Query interval update (lazy) and update or query complexity in log (n) or less (so fast ?? essential travel home Ichiban) contribution is O (n) drops big issue 8

Published 54 original articles · won praise 0 · Views 1230

Guess you like

Origin blog.csdn.net/weixin_44144278/article/details/99131894