HDU 1166 Enemy Array (Line Tree)

Posted by ShootingBlanks on Thu, 06 Jun 2019 20:23:55 +0200

Enemy troops

Topic Links
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 95983 Accepted Submission(s): 40527

Problem Description
Country C's deadly rival, Country A, was conducting military exercises during this period, so Derek, the spy chief of Country C, and Tidy, his men, were busy again. The task of Derek and Tidy is to monitor the activities of N engineering camps along the coastline of State A. As a result of some advanced monitoring methods, the number of each engineer camp is well known in Country C. The number of each engineer camp may change, and it may increase or decrease a number of manpower, but these can not escape the surveillance of Country C.
The CIA wants to study what tactics the enemy is exercising, so Tidy needs to report to Derek at any time how many people there are in a successive engineering camp, such as Derek: "Tidy, report immediately how many people there are from the third camp to the tenth camp!" Tidy needs to start calculating the total number of people in this section and reporting immediately. But the number of enemy barracks often changes, and Derek asks for different sections, so Tidy has to count one camp at a time, and soon exhausted, Derek is increasingly dissatisfied with Tidy's calculation speed: "You are a fat boy, so slow, I fired you squid!" Tidy thought: "You can count it yourself, it's really a tiring job! I hate it!" You fired me! "In desperation, Tidy had to call computer expert Windbreaker for help. Windbreaker said,"Dead fat boy, ask you to do more acm problems and read more algorithmic books at ordinary times. Now you've tasted the bitter fruit!"Tidy said,"I know wrong." But Windbreaker has already hung up. Tidy is distressed, so he's really going to crash, smart reader. Can you write a program to help him do this? But if your program is not efficient enough, Tidy will still be scolded by Derek.

Input
The first line is an integer T, indicating that there are T groups of data.
A positive integer N (N <= 50000) in the first row of each set of data indicates that the enemy has N Engineer barracks, followed by N positive integers, and a positive integer ai in the first row represents an ai individual at the beginning of the first engineer barracks (1 <= ai <= 50).
Next, there is a command on each line. There are four forms of command:
(1) Add i j,i and j are positive integers, representing an increase of J individuals in the first camp (j does not exceed 30)
(2) Sub i j, i and j are positive integers, indicating that the number of J individuals in the first camp is reduced (j does not exceed 30);
(3) Query i j, i and j are positive integers, i <=j, indicating the total number of camps from i to J.
(4)End means the end, and this command appears at the end of each group of data.
Up to 40,000 commands per set of data

Output
For group I data, first output "Case i:" and return.
For each Query query, output an integer and return to indicate the total number of people in the query section, which remains within int.

Sample Input
1
10
1 2 3 4 5 6 7 8 9 10
Query 1 3
Add 3 6
Query 2 7
Sub 10 2
Add 6 3
Query 3 10
End

Sample Output
Case 1:
6
33
59

Author
Windbreaker

This problem can be solved with line segment trees and tree arrays.
First look at the code of the downline segment tree. If you don't know the segment tree, you can look at it first. Segment Tree Summary Link

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
struct
{
    int a,b,sum;
}t[140000];
int r[50010],summ,k;
void buildd(int x,int y,int num)//Structural Segment Tree
{

    t[num].a=x;
    t[num].b=y;
    if(x==y)
        t[num].sum=r[y];
    else
    {
        buildd(x,(x+y)/2,num*2);
        buildd((x+y)/2+1,y,num*2+1);
        t[num].sum=t[num*2].sum+t[num*2+1].sum;
    }
}
void query(int x, int y, int num)//lookup
{
    if(x<=t[num].a&&y>=t[num].b)
        summ+=t[num].sum;
    else{
        int minn=(t[num].a+t[num].b)/2;
        if(x>minn) query(x,y,num*2+1);
        else if(y<=minn)
            query(x,y,num*2);
        else
        {
            query(x,y,num*2);
            query(x,y,num*2+1);
        }
    }
}
void add(int x, int y, int num)//Add to
{
    t[num].sum+=y;
    if(t[num].a==x&&t[num].b==x) return ;
    if (x>(t[num].a+t[num].b)/2) add(x,y,num*2+1);
    else add(x,y,num*2);
}
void sub(int x,int y,int num)//reduce
{
    t[num].sum-=y;
    if(t[num].a==x&&t[num].b==x) return ;
    if(x>(t[num].a+t[num].b)/2) sub(x,y,num*2+1);
    else sub(x,y,num*2);
}
int main()
{
    int t;
    int cnt=0;
    scanf("%d",&t);
    while(t--)
    {
        int n,m;
        char ch[10];
        scanf("%d",&k);
        r[0]=0;
        for(int i=1;i<=k;i++)
            scanf("%d",&r[i]);
        buildd(1,k,1);
        printf("Case %d:\n",++cnt);
        while(scanf("%s",&ch))
        {
            if(strcmp(ch,"End")==0)
                break;
            else if(strcmp(ch,"Query")==0)
            {
                scanf("%d%d",&n,&m);
                summ=0;
                query(n,m,1);
                printf("%d\n",summ);
            }
            else if(strcmp(ch,"Add")==0)
            {
                scanf("%d%d",&n,&m);
                add(n,m,1);
            }
            else if(strcmp(ch,"Sub")==0)
            {
                scanf("%d%d",&n,&m);
                sub(n,m,1);
            }
        }
    }
    return 0;
}

Tree Array Writing. Introduction questions. If you don't understand, you can see the introduction of tree arrays Click on this link

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
int a[500050];
int summ[500050];
int low(int x)//lowbit function, the core of tree array
{
    return x&(-x);
}
void build(int n)//Establishing tree arrays
{
    for(int i=1;i<=n;i++)
    {
        for(int j=i;j>=i-low(i)+1;j--)
            summ[i]+=a[j];
    }
}
int s_sum(int n)//Find the sum before n
{
    int sum=0;
    for(int i=n;i>0;i-=low(i))
        sum+=summ[i];
    return sum;
}
void update(int x,int y,int n)//Modify the tree array
{
    for(int i=x;i<=n;i+=low(i))
        summ[i]+=y;
}
int main()
{
    int t,k,num=1;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&k);
        memset(a,0,sizeof(a));
        memset(summ,0,sizeof(summ));
        for(int i=1;i<=k;i++)
            scanf("%d",&a[i]);
        build(k);
        char x[10];
        int a,b;
        printf("Case %d:\n",num++);
        while(scanf("%s",x))
        {
            if(strcmp(x,"End")==0)
                break;
            scanf("%d%d",&a,&b);
            if(strcmp(x,"Query")==0)
                printf("%d\n",s_sum(b)-s_sum(a-1));
            else if(strcmp(x,"Add")==0)
                update(a,b,k);
            else if(strcmp(x,"Sub")==0)
                update(a,-1*b,k);
        }
    }
    return 0;
}

Topics: Java