Segment tree [training]

 

A. lineup enemy soldiers

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 149073    Accepted Submission(s): 61803


Problem Description
A rival country C country's ongoing military exercises this time, the country's spy chief C Derek 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.
 

 

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 It 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;
each data command to up to 40,000
 

 

Output
Of the i-th group of data, first outputs "Case i:" and enter,
for each Query query, carriage return and output an integer representing the total number of queries in the segment, this number 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
 
Recommend
Eddy
 
Thinking: single-point modification, query section (ah operation-yl group operation
#include <cstdio>
#include <iostream>
#include <cstring>

using namespace std;

typedef long long LL;
const int maxn=1e5+7;

int a[maxn],tree[maxn*4];
int lz[maxn*4];

void build(int node ,int start, int endd)
{
    if(start == endd)//叶子节点
    {
        tree[node] = a[start];
        return ;
    }
    else{
        int mid  = start + ((endd - start) >> 1);
        int lson = node << 1 ;//左儿子:2 * node
        int rson = (node << 1) | 1;//右儿子:2 * node + 1
        build(lson, start, mid);
        build(rson, mid+1, endd);
        tree[node] = tree[lson] + tree[rson];
    } 
}

Void a pushup (int Node) 
{ 
    Tree [Node] = Tree [Node <<. 1] + Tree [Node. 1 << |. 1]; 
} 

// update a single point, idx is a need to update the leaf node number, add to change value 
void Update (Node int, int Start, ENDD int, int IDX, INSTEAD int) 
{ 
    IF (Start == ENDD) 
    { 
        Tree [Node] + = INSTEAD; 
        return; 
    } 
    the else 
    { 
        int MID = Start + ((ENDD - Start) >>. 1); 
        int = LSON (Node <<. 1); 
        int rson = (Node <<. 1) |. 1; 
        IF (IDX <= MID) 
        { 
            Update (LSON, Start, MID, IDX, INSTEAD); 
        } 
        the else 
        {
            update(rson, mid+1, endd, idx, instead);
        }
        pushup(node);
    }
}


LL query(int node, int start, int endd, int l, int r)
{
    if(l <= start && r >= endd)
    {
        return tree[node];
    }
   // pushdown(node, start, endd);
    int mid = start + ((endd-start)>>1);
    LL ans=0;
    if(l <= mid) ans+=query(node<<1, start, mid, l, r);
    if(r >= mid+1) ans+=query(node<<1|1, mid+1, endd, l, r);
    return ans;
}

int main()
{
    int t;
    scanf("%d",&t);
    int cas=1;
    while(t--){
        printf("Case %d:\n",cas++);
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        build(1,1,n);
        char str[10];
        while(scanf("%s",str)!=EOF){

            if(!strcmp(str,"End")) break;
            if(!strcmp(str,"Add"))
            {
                int idx,ad;
                scanf("%d%d",&idx,&ad);
                update(1,1,n,idx,ad);
            }
            if(!strcmp(str,"Sub"))
            {
                int idx,ad;
                scanf("%d%d",&idx,&ad);
                update(1,1,n,idx,-ad);
            }
            if(!strcmp(str,"Query"))
            {
                int l,r;
                scanf("%d%d",&l,&r);
                //for(int i=1;i<=25;i++) printf("tree[%d]:%d\n",i,tree[i]);
                printf("%lld\n",query(1,1,n,l,r));
            }


        }
    }
    return 0;
}

 

B.I Hate It

Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 123585    Accepted Submission(s): 45493


Problem Description
A more popular habit of many schools. The teachers really like to ask, so and so to so and so from among the highest score is.
This allows many students are disgusted.

Whether you like it or not, now you need to do is, it is in accordance with the requirements of the teacher, to write a program to simulate the teacher asked. Of course, teachers sometimes need to update certain students achievements.
 

 

Input
This topic contains multiple sets of test, to deal with the end of the file.
In the first line of each test, there are two positive integers N and M (0 <N <= 200000,0 <M <5000), represents the number of operations and the number of students.
Student ID numbers are compiled from 1 to N.
The second line contains N integers, representing the N initial student grades, where the i-th student ID is representative of the results i.
The next M rows. Each line has a character C (just take 'Q' or 'U'), and two positive integers A, B.
When C is the 'Q' time, that this is a query operation, it queries the ID from A to B (including A, B) among the students, the highest score is.
When C is the 'U' time, that this is an update operation, the ID required to change grades A student B.
 

 

Output
For each query operation, which outputs the highest score in a row.
 

 

Sample Input
5 6
1 2 3 4 5
Q 1 5
In 3 6
Q 3 4
Q 4 5
In 2 9
Q 1 5
 
Sample Output
5
6
5
9
Hint
Huge input,the C function scanf() will work better than cin
 

 

Author
linle
 
Source
 
Recommend
lcy
 
Idea: a single point of modification, the maximum interval (board ah board
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define max2(a,b) a>b?a:b

using namespace std;

typedef long long LL;
const int maxn=2e5+9;

LL mac(LL a,LL b)
{
    return a>=b?a:b;
}
LL a[maxn];
LL tree[maxn*4];
LL lz[maxn*4];

void pushup(LL node)
{
    tree[node] = mac(tree[node<<1],tree[node<<1|1]);
}

void build(LL node ,LL start, LL endd)
{
    if(start == endd)//叶子节点
    {
        tree[node] = a[start];
        return ;
    }
    else{
        LL mid  = (start + endd) >> 1;
        //LL lson = node << 1 ;
        //LL rson = (node << 1) | 1;
        build(node<<1, start, mid);
        build((node<<1)|1, mid+1, endd);
        pushup(node);
    }
}

void update(LL node, LL start, LL endd, LL idx, LL instead)
{
    //prLLf("node:%d\n",node);
    if(start == endd)
    {
        tree[node] = instead;
        return ;
    }

    LL mid  = (start + endd) >> 1;
    LL lson = (node << 1);
    LL rson = (node << 1) | 1;
    if( idx <= mid)
    {
        update(lson, start, mid, idx, instead);
    }
    else
    {
        update(rson, mid+1, endd, idx, instead);
    }
    pushup(node);

    //pushup(node);
}

LL query(LL node, LL start, LL endd, LL l, LL r)
{
    //printf("node2:%d\n",node);
    if(l <= start && r>=endd)
    {
        return tree[node];
    }
    //push_down(node, start, endd);
    LL mid = (start + endd)>>1;

    LL ansl=0;
    LL ansr=0;
    if(l <= mid)   ansl = query( node<<1, start, mid, l, r);
    if(r >= mid+1) ansr = query( node<<1|1, mid+1, endd, l, r);

    return mac(ansl,ansr);
}
char ch[10];
int main()
{
    LL n,m;
    while(scanf("%lld%lld",&n,&m)!=EOF){
    for(LL i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
    }
    getchar();
    build(1,1,n);
    while(m--)
    {
        scanf("%s",ch);
        if(ch[0]=='Q')
        {
            LL l,r;
            scanf("%lld%lld",&l,&r);
            //for(int i=1;i<=50;i++) printf("tree[%d]:%d\n",i,tree[i]);
            printf("%lld\n",query(1,1,n,l,r));
        }
        if(ch[0]=='U')
        {
            LL idx,ad;
            scanf("%lld%lld",&idx,&ad);
            update(1,1,n,idx,ad);
        }
    }
    }
    return 0;
}

Why hdu will tle with max Curry? ? ?

 

C.Computers
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 2144   Accepted: 911

Description

Everybody is fond of computers, but buying a new one is always a money challenge. Fortunately, there is always a convenient way to deal with. You can replace your computer and get a brand new one, thus saving some maintenance cost. Of course, you must pay a fixed cost for each new computer you get.

Suppose you are considering an n year period over which you want to have a computer. Suppose you buy a new computer in year y, 1<=y<=n Then you have to pay a fixed cost c, in the year y, and a maintenance cost m(y,z) each year you own that computer, starting from year y through the year z, z<=n, when you plan to buy - eventually - another computer.

Write a program that computes the minimum cost of having a computer over the n year period.

Input

The program input is from a text file. Each data set in the file stands for a particular set of costs. A data set starts with the cost c for getting a new computer. Follows the number n of years, and the maintenance costs m(y,z), y=1..n, z=y..n. The program prints the minimum cost of having a computer throughout the n year period.

White spaces can occur freely in the input. The input data are correct and terminate with an end of file.

Output

For each set of data the program prints the result to the standard output from the beginning of a line.

Sample Input

3
3
5 7 50
6 8
10

Sample Output

19

Hint

An input/output sample is shown above. There is a single data set. The cost for getting a new computer is c=3. The time period n is n=3 years, and the maintenance costs are:

  • For the first computer, which is certainly bought: m(1,1)=5, m(1,2)=7, m(1,3)=50,
  • For the second computer, in the event the current computer is replaced: m(2,2)=6, m(2,3)=8,
  • For the third computer, in the event the current computer is replaced: m(3,3)=10.

Source

 
Thinking: how seniors pulled Road dp title came in? ? ? Each year choose to buy or not to buy, buy choose n in insurance.
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

int dp[1007][1007];

int main()
{
    int c;
    while(scanf("%d",&c)!=EOF)
    {
        memset(dp,0,sizeof(dp));
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            for(int j=i;j<=n;j++)
            {
                scanf("%d",&dp[i][j]);
            }
        }

        for(int i=1;i<=n;i++)
        {
            for(int j=i;j<=n;j++)
            {
                if(i==1)
                {
                    dp[i][j]+=c;
                }
                else
                    dp[i][j]=(dp[i-1][i-1]+dp[i][j]+c)<(dp[i-1][j])?(dp[i-1][i-1]+dp[i][j]+c):(dp[i-1][j]);
                //printf("dp[%d][%d]:%d\n",i,j,dp[i][j]);
            }
        }
        printf("%d\n",dp[n][n]);
    }
    return 0;
}

 

D will not do ah Gan

E.Just a Hook

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 52820    Accepted Submission(s): 24709


Problem Description
In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of the heroes. The hook is made up of several consecutive metallic sticks which are of the same length.



Now Pudge wants to do some operations on the hook.

Let us number the consecutive metallic sticks of the hook from 1 to N. For each operation, Pudge can change the consecutive metallic sticks, numbered from X to Y, into cupreous sticks, silver sticks or golden sticks.
The total value of the hook is calculated as the sum of values of N metallic sticks. More precisely, the value for each kind of stick is calculated as follows:

For each cupreous stick, the value is 1.
For each silver stick, the value is 2.
For each golden stick, the value is 3.

Pudge wants to know the total value of the hook after performing the operations.
You may consider the original hook is made up of cupreous sticks.
 

 

Input
The input consists of several test cases. The first line of the input is the number of the cases. There are no more than 10 cases.
For each case, the first line contains an integer N, 1<=N<=100,000, which is the number of the sticks of Pudge’s meat hook and the second line contains an integer Q, 0<=Q<=100,000, which is the number of the operations.
Next Q lines, each line contains three integers X, Y, 1<=X<=Y<=N, Z, 1<=Z<=3, which defines an operation: change the sticks numbered from X to Y into the metal kind Z, where Z=1 represents the cupreous kind, Z=2 represents the silver kind and Z=3 represents the golden kind.
 

 

Output
For each case, print a number in a line representing the total value of the hook after the operations. Use the format in the example.
 

 

Sample Input
1
10
2
1 5 2
5 9 3
 

 

Sample Output
Case 1: The total value of the hook is 24.
 

 

Source
 
Recommend
wangye
 
Idea: modify the interval, the interval query
 
#include <cstdio>
#include <iostream>
#include <cstring>

using namespace std;
const int maxn=1e5+7;
typedef long long LL;

int tree[maxn*4];
int lz[maxn*4];
int a[maxn];

//区间改值,区间查询
void pushup(int node)
{
    tree[node] = tree[node<<1] + tree[node<<1|1];
}

void pushdown(int node, int start, int endd)
{
    if(lz[node])
    {
        int c = lz[node];
        lz[node<<1]   = c;
        lz[node<<1|1] = c;
        int mid = start + ((endd - start)>>1);
        tree[node<<1] = (mid-start+1) * c;
        tree[node<<1|1] = (endd-mid) * c;
        lz[node] = 0;
    }
}

void build(int node ,int start, int endd)
{
    lz[node] = 0;
    if(start == endd)//叶子节点
    {
        tree[node] = a[start];
        return ;
    }
    else{
        int mid  = start + ((endd - start) >> 1);
        int lson = node << 1 ;//左儿子:2 * node
        int rson = (node << 1) | 1;//右儿子:2 * node + 1
        build(lson, start, mid);
        build(rson, mid+1, endd);
        //tree[node] = tree[lson] + tree[rson];
    }
    pushup(node);
}



void update(int node, int start, int endd, int l, int r,int c)
{
    if(l <= start && r >= endd)
    {
        //tree[node] = (endd-start+1) * lz[node];
        lz[node]   = c;
        tree[node] = (endd-start+1) * c;
       // printf("latree[%d]:%d\n",node,tree[node]);
        return ;
    }
    pushdown(node, start, endd);
    int mid = start + ((endd - start)>>1);
    if(l <= mid) update(node<<1, start, mid, l, r, c);
    if(r >= mid+1) update(node<<1|1, mid+1, endd, l, r,c);
    pushup(node);
   // printf("tree[2]:%d\n",tree[2]);
}

LL query(int node, int start, int endd, int l, int r)
{
    if(l <= start && r >= endd)
    {
        return tree[node];
    }
    pushdown(node, start, endd);
    int mid = start + ((endd-start)>>1);
    LL ans=0;
    if(l <= mid) ans+=query(node<<1, start, mid, l, r);
    if(r >= mid+1) ans+=query(node<<1|1, mid+1, endd, l, r);
    return ans;
}

int main()
{
    int t;
    scanf("%d",&t);
    int x=1;
    while(t--)
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) a[i]=1;
        build(1,1,n);
        int q;
        scanf("%d",&q);
        while(q--)
        {
            int l,r,z;
            scanf("%d%d%d",&l,&r,&z);
            update(1,1,n,l,r,z);
            //for(int i=1;i<26;i++) printf("tree[%d]:%d\n",i,tree[i]);
        }
        printf("Case %d: The total value of the hook is %lld.\n",x++,query(1,1,n,1,n));
    }
    return 0;
}

 

Hihocoder # 1078: Interval tree line changes

Time limit: 10000ms
A single point of time: 1000ms
Memory Limit: 256MB

description

For small Ho showed understanding of the tree line, the small Hi represents quite satisfied, but satisfaction enough it? So the question Hi little changed changed, and out to a small Ho:

Suppose placed from left to right on the shelves of the N kinds of products, and sequentially numbered 1 to N, where i designated commodity prices for Pi. Small Hi of each operation may be divided into two types, one is the first to modify the price - Hi gives some small interval [L, R] newp and a new price, commodity prices all labels in this interval are become newP. The second operation is to ask - small Hi given period interval [L, R], while the small Ho to do is figure out all the numbers of the total price of the commodity during this interval, and then told a small Hi.

Then such a problem, small Ho how to solve it?

Tip: In addition to promoting scientific development of people's curiosity was also lazy heart!

Entry

Each test point (input file) and only a set of test data.

The first behavior Each test an integer N, as previously described meaning.

The second behavior N integers each test, the weight of each item are described, wherein the integer represents the i-th numbered items i weight of Pi.

3 a Each test behavior integer Q, operands small Hi performed.

The first N + 4 ~ N + Q + 3 rows each test, a description of operations for each row, are beginning of each line belonging to a number 0 or 1, each row indicates the challenge and a description of a commodity price changes in both cases. For the first row + i + 3 N, if the row describes a query, the next two integer of Li, Ri, represents a small Hi inquiry interval [Li, Ri]; if the price of a commodity row describes changes , the next three integer of Li, Ri, newP, commodity price represents numerals interval [Li, Ri] to all modifications newP.

To 100% of the data satisfies N <= 10 ^ 5, Q <= 10 ^ 5, 1 <= Li <= Ri <= N, 1 <= Pi <= N, 0 <Pi, NewP <= 10 ^ 4 .

Export

For each test, small Hi for each interrogation of the order they appear in the input, each output line, shows the results of a query: the price of the goods all the reference numerals in the interval [Li, Ri] and the.

Sample input
10
4733 6570 8363 7391 4511 1433 2281 187 5166 378 
6
1 5 10 1577
1 1 7 3649
0 8 10
0 1 4
1 6 8 157
1 3 4 1557
Sample Output
4731 
14596 

idea: modify the interval, the interval query
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#define LL long long

using namespace std;
const int maxn=1e5+7000;
int tree[maxn*4];
int a[maxn];
int change[maxn*4];
int lz[maxn*4];

void build(int node ,int start, int endd)
{
    if(start == endd)//叶子节点
    {
        tree[node] = a[start];
        //printf("node:%d\n",node);
        return ;
    }
    else{
        int mid  = start + ((endd - start) >> 1);
        int lson = node << 1 ;//左儿子:2 * node
        int rson = (node << 1) | 1;//右儿子:2 * node + 1
        build(lson, start, mid);
        build(rson, mid+1, endd);
        tree[node] = tree[lson] + tree[rson];
    }
}

void pushup(int node)
{
    tree[node] = tree[node<<1] + tree[node<<1|1];
}

void pushdown(int node, int start, int endd)
{
    //printf("node2:%d\n",node);
    if(change[node])
    {
        int c = change[node];
        change[node<<1]   = c;
        change[node<<1|1] = c;
        int mid = start + ((endd-start)>>1);
        tree[node<<1] = (mid-start+1) * c;
        tree[node<<1|1] = (endd-mid) * c;
        change[node] = 0;
    }
}

void update(int node, int start, int endd, int l, int r,int c)
{
    if(l <= start && r >= endd)
    {
        change[node] = c;
        tree[node] = (endd-start+1) * c;
        return ;
    }
    pushdown(node, start, endd);
    int mid = start + ((endd - start)>>1);
    if(l <= mid) update(node<<1, start, mid, l, r, c);
    if(r >= mid+1) update(node<<1|1, mid+1, endd, l, r,c);
    pushup(node);
}

int query(int node, int start, int endd, int l, int r)
{
    //printf("!\n");
    if(l <= start && r >= endd)
    {
        //printf("node3:%d\n",node);
        return tree[node];
    }
    pushdown(node, start, endd);
    int mid = start + ((endd-start)>>1);
    int ans=0;
    if(l <= mid) ans+=query(node<<1, start, mid, l, r);
    if(r >= mid+1) ans+=query(node<<1|1, mid+1, endd, l, r);
    return ans;
}

int main()
{
    int t;
    scanf("%d",&t);
    for(int i=1;i<=t;i++)
    {
        scanf("%d",&a[i]);
    }
    build(1,1,t);
    int n;
    scanf("%d",&n);
    while(n--)
    {
        int x,l,r,c;
        scanf("%d%d%d",&x,&l,&r);
        if(x==1)
        {
            scanf("%d",&c);
            update(1,1,t,l,r,c);
        }
        else
        {
            /*for(int i=1;i<50;i++)
            {
                printf("tree[%d]:%d\n",i,tree[i]);
            }*/
            printf("%d\n",query(1,1,t,l,r));
        }
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/orangeko/p/11300076.html