1. 程式人生 > >HDU4027Can you answer these queries?(線段樹區間和,坑)

HDU4027Can you answer these queries?(線段樹區間和,坑)

Can you answer these queries?

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 8674 Accepted Submission(s): 1971


Problem Description A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use our secret weapon to eliminate the battleships. Each of the battleships can be marked a value of endurance. For every attack of our secret weapon, it could decrease the endurance of a consecutive part of battleships by make their endurance to the square root of it original value of endurance. During the series of attack of our secret weapon, the commander wants to evaluate the effect of the weapon, so he asks you for help.
You are asked to answer the queries that the sum of the endurance of a consecutive part of the battleship line.

Notice that the square root operation should be rounded down to integer.

Input The input contains several test cases, terminated by EOF.
For each test case, the first line contains a single integer N, denoting there are N battleships of evil in a line. (1 <= N <= 100000)
The second line contains N integers Ei, indicating the endurance value of each battleship from the beginning of the line to the end. You can assume that the sum of all endurance value is less than 263
.
The next line contains an integer M, denoting the number of actions and queries. (1 <= M <= 100000)
For the following M lines, each line contains three integers T, X and Y. The T=0 denoting the action of the secret weapon, which will decrease the endurance value of the battleships between the X-th and Y-th battleship, inclusive. The T=1 denoting the query of the commander which ask for the sum of the endurance value of the battleship between X-th and Y-th, inclusive.

Output For each test case, print the case number at the first line. Then print one line for each query. And remember follow a blank line after each test case.
Sample Input 10 1 2 3 4 5 6 7 8 9 10 5 0 1 10 1 1 10 1 1 5 0 5 8 1 4 8
Sample Output Case #1: 19 7 6
Source 0:區間每個數開平方根取整。 1:區間和
#include<stdio.h>
#include<math.h>
#define N 100100
struct nn
{
    int flag;//為0,說明這個區間內的數全為1
    __int64 sum;//區間和
}tree[N*3];
void builde(int l,int r,int k)
{
    int m=(l+r)/2;
    if(l==r)
    {
        scanf("%I64d",&tree[k].sum);
      tree[k].flag=1;if(tree[k].sum<=1)tree[k].flag=0; return ;
    }
    builde(l,m,k*2);
    builde(m+1,r,k*2+1);
    tree[k].sum=tree[k*2].sum+tree[k*2+1].sum;
    tree[k].flag=tree[k*2].flag|tree[k*2+1].flag;
}
void updata(int l,int r,int k,int L,int R)
{
    int m=(r+l)/2;
    if(l==r)
    {
        tree[k].sum=(__int64)sqrt(1.0*tree[k].sum);
        if(tree[k].sum<=1)tree[k].flag=0; return ;
    }
    if(L<=m&&tree[k*2].flag)updata(l,m,k*2,L,R);
    if(R>m&&tree[k*2+1].flag)updata(m+1,r,k*2+1,L,R);
    tree[k].sum=tree[k*2].sum+tree[k*2+1].sum;
    tree[k].flag=tree[k*2].flag|tree[k*2+1].flag;
}
__int64 query(int l,int r,int k,int L,int R)
{
    int m=(l+r)/2;
    if(L<=l&&r<=R)
    {
        return tree[k].sum;
    }
    __int64 sum=0;
    if(L<=m)sum+=query(l,m,k*2,L,R);
    if(R>m)sum+=query(m+1,r,k*2+1,L,R);
    return sum;
}
int main()
{
    int n,m,t=0,o,L,R;
    while(scanf("%d",&n)>0)
    {
        builde(1,n,1);
        scanf("%d",&m);
        printf("Case #%d:\n",++t);
        while(m--)
        {
            scanf("%d%d%d",&o,&L,&R);
            int tem;
            if(L>R){tem=L;L=R;R=tem;}//注意了
            if(o==0)updata(1,n,1,L,R);
            else
                printf("%I64d\n",query(1,n,1,L,R));
        }
        printf("\n");
    }
    return 0;
}


相關推薦

HDU4027Can you answer these queries?(線段區間)

Can you answer these queries? Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others) Total Submission(s): 8674

HDOJ 4027 Can you answer these queries?(線段+區間標記)

The input contains several test cases, terminated by EOF.    For each test case, the first line contains a single integer N, denoting there are N battleshi

HDU 4027 Can you answer these queries?(線段 區間不等更新)

題意  輸入n個數  然後有兩種操作   輸入0時將給定區間所有數都變為自己的開方   輸入1輸出給定區間所有數的和 雖然是區間更新  但每個點更新的不一樣  因此只能對單點進行更新  其實一個點最多被更新7次  2^64開平方7次後就變為1了  如果某個區間的數都變為了1

Can you answer these queries?(線段區間更新更新到點)

題目 連結:傳送門 A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use our secret weapon to

HDU 4027 Can you answer these queries?(線段單點更新)

Can you answer these queries? Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) Total Submission(s): 13

HDU 4027 Can you answer these queries? [線段]

題意:給你長度為n的數列,m個操作,有兩種操作型別: ①區間[L,R]每個數開根號 ②詢問區間[L,R]的和 題解:由於每個數能開根號的次數很少,當區間和為區間長度的時候,說明該區間全為1了,所以不必要更新下去,所以我們可以減少更新線段樹的複雜度。 注意:輸入的L不一定小於

HDU - 4027 Can you answer these queries? (線段)

tar main 區間求和 hup target 代碼 name upd memset 題目傳送門:HDU - 4027 Can you answer these queries? 題目大意: 存在n艘敵軍戰艦,每艘戰艦都有能量值,我軍存在一種秘密武器,每次能夠將在該

HDU 4027 Can you answer these queries?(線段區間開方)

sizeof sqrt .cn swap %d nes nts following clr Can you answer these queries? Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 6576

HDU 4027 Can you answer these queries?(線段/區間不等更新)

push battle mark put action light blog acc lang 傳送門 Can you answer these queries? Time Limit: 4000/2000 MS (Java/Others) Memory Limi

SP1043 GSS1 - Can you answer these queries I(線段區間最大子段(靜態))

有一種 nbsp 不用 端點 合並 表示 格式 space iostream 題目描述 給出了序列A[1],A[2],…,A[N]。 (a[i]≤15007,1≤N≤50000)。查詢定義如下: 查詢(x,y)=max{a[i]+a[i+1

hdoj 4027 Can you answer these queries? 【線段 區間減為平方 + 區間求和】

The input contains several test cases, terminated by EOF.   For each test case, the first line contains a single integer N, denoting there are N battleshi

hdu 4027 Can you answer these queries?(線段——區間更新)(思路)

Can you answer these queries? Problem Description A lot of battleships of evil are arranged in a line before the battle. Our comm

Can you answer these queries? HDU - 4027(線段+技巧)

fin 題意 ios fff PE sqrt += 長度 scan 題意:給一個數組序列, 數組長度為100000 兩種操作: 一種操作是將某一個固定區間所有數開方(向下取整) 另一種操作是詢問某個區間的所有數字之和。 由於數不超過263,因此開個七八次就變成1,由於只有

SP1557 GSS2 - Can you answer these queries II(線段

傳送門   線段樹好題 因為題目中相同的只算一次,我們可以聯想到HH的項鍊,於是考慮離線的做法 先把所有的詢問按$r$排序,然後每一次不斷將$a[r]$加入線段樹 線段樹上維護四個值,$sum,hix,sumtag,hixtag$,分別代表當前節點的值,節點歷史上的最大值,當前的增加標記,

HDU 4027 Can you answer these queries? (線段+暴力)

題意: 給出一段序列和兩種操作,第一種操作,將x,y區間的數均開平方,第二種操作,對x,y區間進行求和。 分析: 一開始還不敢用線段樹做,因為純線段樹下來根暴力列舉複雜度差不了多少,但由於開方,所以在很少次的迴圈裡就能達到1,所以就可以直接這麼做了。但題目沒有說名忍耐值的範圍,要是0太多

SP2713 GSS4 - Can you answer these queries IV(線段)

def for turn put spa main 是否 case 每次 傳送門 解題思路   大概就是一個數很少次數的開方會開到\(1\),而\(1\)開方還是\(1\),所以維護一個和,維護一個開方標記,維護一個區間是否全部為\(1/0\)的標記。然後每次修改時先看是否

線段--SP2916 GSS5 - Can you answer these queries V

傳送門 以前講過的題,會最大子段和然後分類討論一下就好了 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cma

Can you answer these queries? (線段

Can you answer these queries? A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use our s

2018.10.16 spoj Can you answer these queries V(線段

傳送門 線段樹經典題。 就是讓你求左端點在[l1,r1][l1,r1][l1,r1]之間,右端點在[l2,r2][l2,r2][l2,r2]之間且滿足l1≤l2,r1≤r2l1\le l2,r1 \le

GSS1 - Can you answer these queries I(線段

stdin for ref get stdlib.h 中間 you () == 前言 線段樹菜雞報告,stO ZCDHJ Orz,GSS基本上都切完了。 Solution 考慮一下用線段樹維護一段區間左邊連續的Max,右邊的連續Max,中間的連續Max還有總和,發現這些東西