HDU 1166 Enemy Soldiers--(interval and) tree array/segment tree

Source: Internet
Author: User


here:http://acm.hdu.edu.cn/showproblem.php?pid=1166


Input The first line is an integer t. Represents a T group of data.
The first row of each group of data is a positive integer n (n<=50000), indicating that the enemy has N Corps of Engineers camp. Next there are n positive integers, and the first I positive integer AI represents the AI individual (1<=ai<=50) at the beginning of the field of the first I barracks.
Next, each line has a command. There are 4 forms of the command:
(1) Add I j,i and J are positive integers, indicating that I camp add J person (J not more than 30)
(2) Sub i J, I and J are positive integers, indicating that the I camp lowers J person (J not more than 30);
(3) Query i J, I and J are positive integers, i<=j, which indicate the total number of persons who have inquired about the first and the J camps;
(4) End indicates the ending. This command appears at the end of each set of data;
Up to 40,000 commands per set of data
  Output for Group I data, first output "case I:" and carriage return,
For each query, output an integer and enter it to indicate the total number of people in the segment you are asking for, which remains within Int.
 
Sample Input
  Sample Output
Case 1:63,359
 

The One:

This is an interval summation problem that can be done with a tree array:

Before this. It is necessary to understand that the rules computed by bitwise AND operator--&; are only if two numbers are true. The result is true.

For example, 90&45==8 —————— due to 0101 1010 in binary &

0010 1101 (45) = = 0000 1000 (8)

Attached 1: Negative numbers are stored in the computer: in the form of a complement, that is, the absolute value of negative values of the binary inverse plus one.

such as 1001 (9)-0110 (inversion)-0111 (+1) so 0111 (-9)

How to understand?-9 can be regarded as 0-(9). Based on elementary school knowledge, converted into binary,

                      &NBS P                          ,         &NB Sp                          ,         &NB Sp                              0000 0000 0000 000 0 (0)

                      &NBS P                          ,         &NB Sp                          ,         &NB Sp                      -     0000 0000 0000 1001 &NB SP; (9) Insufficient bit. You have to borrow one forward. Then it becomes:

                      &NBS P                          ,         &NB Sp                          ,         &NB Sp                            1 0000 0000 0000 0000 &NB SP; (0)

-0000 0000 0000 1001 (9) = = 1111 1111 1111 0111 (-9)

Why can we get it by taking the anti-plus one? Be able to write the above 1 0000 0000 0000 0000 as 1111 1111 1111 1111 + 0000 0000 0000 0001, then 0-9 = = 1111 1111 1111 1111-0000 0000 0000 1001 the reverse process then + 0000 0000 0000 0001 is the addition of a process.


Attached to the meaning of 2:-x&x. From the above , the value obtained from this formula is the part after the first 1 of the positive bits. Contains 1, the resulting number must be 2^n, which is of great significance to the tree-like array. In addition, the number of binary end 0 of a number can be obtained at high speed.

Code: Tree-like array

#include <stdio.h> #include <string.h> #define MAX 50005int c[max];int lowbit (int t) {return t& (-T);}    int getsum (int n) {int sum=0;        while (n>0) {sum+=c[n];    N-=lowbit (n); } return sum;}        void change (int i,int v,int N) {while (i<=n) {c[i]+=v;    I+=lowbit (i);    }}int Main () {int t;    scanf ("%d", &t);        for (int j=1;j<=t;j++) {memset (c,0,sizeof (c));        printf ("Case%d:\n", j);        int n,a;        scanf ("%d", &n);            for (int i=1;i<=n;i++) {scanf ("%d", &a);        Change (i,a,n);        } Char cmd[10];            while (scanf ("%s", cmd), cmd[0]!= ' E ') {int p,q;                if (cmd[0]== ' A ') {scanf ("%d%d", &p,&q);            Change (p,q,n);                } else if (cmd[0]== ' S ') {scanf ("%d%d", &p,&q);            Change (p,-q,n);  } else {              scanf ("%d%d", &p,&q);                if (p!=1) printf ("%d\n", Getsum (q)-getsum (p-1));            else printf ("%d\n", Getsum (q)); }}} return 0;}

Figures:



Hope to be able to better understand the process of summation.

In fact, the quality is a binary index tree


Why:

A little taller is done with a line tree.

Here I am using an array to simulate a completely binary tree, the basic storage principle is to assume a one-dimensional array to save a binary tree. Suppose the subscript starts from the beginning. Father node by 2 is the left son node, the Father node by 2 plus one is the right son node. The son node divided by two is the Father node. The fact that the principle is almost identical to the tree array above is just a different way of implementing it.

Code

#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include < math.h> #include <string> #include <stack> #include <queue> #include <map> #define MAX (A, b) (a ) > (b)? (a):(B) #define INF 0x3f3f3f3f#define Lson l,m,rt<<1//Find left son # define Rson m+1,r,rt<<1|1//find right son # define M 50008using namespace Std;int segtree[m<<2];//size for nodes four times times//Father node Save left and right son node and inline void Pushrt (int rt) {Segtree[rt] = SE GTREE[RT&LT;&LT;1] + segtree[rt<<1|1];}        void build (int l, int r, int rt) {if (L = = r) {scanf ("%d", &segtree[rt]);    return;    } int m = (L + r) >>1;     Recursive achievement Build (Lson);    Build (Rson); Pushrt (RT);}        Single-point update void Update (int p, int add, int l, int r, int rt) {if (L = = r) {segtree[rt]+=add;    return;    } int m= (L + R) >>1;    Recursive update if (P <= m) update (p, add, Lson);    else Update (p, add, Rson); Pushrt (RT);} int query (int l, int r, int l, int r, int RT) {//Assume that l,r directly returns the IF (L <= l&&r<= R) return SEGTREE[RT] within the range queried;    int m= (L + R) >>1;    int ans=0;    Recursive query if (l <= m) ans+=query (L, R, Lson);    if (R > M) ans+=query (L, R, Rson); return ans;}    int main () {int n,t,p,q,o=1;    scanf ("%d", &t);        while (t--) {scanf ("%d", &n);        Build (1,n,1);        printf ("Case%d:\n", o++);        Char op[10];            while (scanf ("%s", op) &&op[0]!= ' E ') {scanf ("%d%d", &p,&q);            if (op[0]== ' Q ') printf ("%d\n", Query (p,q,1,n,1));            else if (op[0]== ' A ') update (p,q,1,n,1);        else update (p,-q,1,n,1); }} return 0;}

This is a segment tree that belongs to a single point update. The place of recursion is more difficult to understand. Debug it and you'll probably understand it faster. In addition, in order to perform a faster bit operation, understand the left shift right shift and OR operation is OK.


HDU 1166 Enemy Soldiers--(interval and) tree array/segment tree

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.