V - Can you answer these queries? HDU - 4027 线段树

V - Can you answer these queries?

HDU - 4027

这个题目开始没什么思路,因为不知道要怎么去区间更新这个开根号。

然后稍微看了一下题解,因为每一个数开根号最多开十几次就变成1了,所以就直接单点更新,但是这个可以剪枝。

如果碰到区间长度和区间大小相同就可以不用更新了。

我也是无语了,想到刚刚的做法之后很好写了,

不过要注意以下x,y 大小可能x>y, 这个bug如果不是之前看题解的时候瞄到了,我可能找不出来了。

因为我写对拍我肯定会保证x<y 的,还是就是注意看清楚题目要求输出一行空行。

#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn = 1e5 + 10;
typedef long long ll;
struct node
{
    ll len, sum;
}tree[maxn*8];
ll a[maxn];

void push_up(int id)
{
    tree[id].sum = tree[id << 1].sum + tree[id << 1 | 1].sum;
}

void build(int id,int l,int r)
{
    tree[id].len = r - l + 1;
    if(l==r)
    {
        tree[id].sum = a[l];
        return;
    }
    int mid = (l + r) >> 1;
    build(id << 1, l, mid);
    build(id << 1 | 1, mid + 1, r);
    push_up(id);
}

void update(int id,int l,int r,int x,int y)
{
    if (x <= l && y >= r && tree[id].len == tree[id].sum) return;
    if(l==r)
    {
        tree[id].sum = sqrt(tree[id].sum);
        return;
    }
    int mid = (l + r) >> 1;
    if (x <= mid) update(id << 1, l, mid, x, y);
    if (y > mid) update(id << 1 | 1, mid + 1, r, x, y);
    push_up(id);
}

ll query(int id,int l,int r,int x,int y)
{
    if(x<=l&&y>=r) return tree[id].sum;
    int mid = (l + r) >> 1;
    ll ans = 0;
    if (x <= mid) ans += query(id << 1, l, mid, x, y);
    if (y > mid) ans += query(id << 1 | 1, mid + 1, r, x, y);
    return ans;
}

int main()
{
    int n, m, cas = 1;
    while(scanf("%d", &n)!=EOF)
    {
        for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
        build(1, 1, n);
        scanf("%d", &m);
        cout << "Case #" << cas++ << ":" << endl;
        while(m--)
        {
            int opt, x, y;
            scanf("%d%d%d", &opt, &x, &y);
            if (x > y) swap(x, y);
            if(opt==0) update(1, 1, n, x, y);
            else
            {
                ll ans = query(1, 1, n, x, y);
                printf("%lld\n", ans);
            }
        }
        printf("\n");
    }
    return 0;
}

线段树

原文地址:https://www.cnblogs.com/EchoZQN/p/11276060.html

时间: 2024-08-11 03:33:44

V - Can you answer these queries? HDU - 4027 线段树的相关文章

spoj gss2 : Can you answer these queries II 离线&amp;&amp;线段树

1557. Can you answer these queries II Problem code: GSS2 Being a completist and a simplist, kid Yang Zhe cannot solve but get Wrong Answer from most of the OI problems. And he refuse to write two program of same kind at all. So he always failes in co

Can you answer these queries? HDU - 4027

Can you answer these querites? HDU - 4027 普通的线段树题,但是有一个问题是,区间更新时,因为必须更新每个点,才能更新区间,那么线段树更新就很慢了,无法使用lazy数组.有一个小技巧是当区间和等于区间长度时,那么说明已经到最好的情况了,不用再修改了.这一步简化后就可以过了 如果写线段树可以像喝水一样自然就好了 1 #include <iostream> 2 #include <cstring> 3 #include <vector>

H - Can you answer these queries? HDU 4027 (线段树+延迟标记+开根号的速度)

H - Can you answer these queries? Time Limit:2000MS Memory Limit:65768KB 64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4027 Description A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use our

SPOJ GSS2 - Can you answer these queries II(线段树 区间修改+区间查询)(后缀和)

GSS2 - Can you answer these queries II #tree Being a completist and a simplist, kid Yang Zhe cannot solve but get Wrong Answer from most of the OI problems. And he refuse to write two program of same kind at all. So he always failes in contests. When

Can you answer these queries? HDU - 4027 有点坑

#include<iostream> #include<cstring> #include<cstdio> #include<math.h> #include<algorithm> using namespace std; typedef long long ll; const int N=1e5+10; ll a[N]; int n,m; int op,l,r; struct node { ll l,r; ll sum; }tr[N*4]; v

spoj 1716 Can you answer these queries III(线段树)

和I相比有了单点更新,所以不能只记录一个前缀和,而是要在线段树上多维护一个sum,表示这个结点的区间和,然后其他的就和I一样了. #include <iostream>#include <cstring>#include <cstdio>using namespace std; const int N = 50001;int a[N]; struct Node { int l, r, sum; int maxl, maxr, maxn;} node[N <<

Spoj 2713 Can you answer these queries IV 水线段树

题目链接:点击打开链接 题意: 给定n长的序列 下面2个操作 0 x y 给[x,y]区间每个数都 sqrt 1 x y 问[x, y] 区间和 #include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> #include <queue> #include <math.h> #include <vector> #includ

【SPOJ - GSS2】Can you answer these queries II(线段树)

区间连续不重复子段最大值,要维护历史的最大值和当前的最大值,打两个lazy,离线 #include<cstdio> #include<cstring> #include<algorithm> #define maxn 150000 #define rep(i,l,r) for(int i=l;i<=r;i++) #define LL long long using namespace std; typedef struct { LL nmax,hmax,nlazy

SP1043 GSS1 - Can you answer these queries I(线段树,区间最大子段和(静态))

题目描述 给出了序列A[1],A[2],…,A[N]. (a[i]≤15007,1≤N≤50000).查询定义如下: 查询(x,y)=max{a[i]+a[i+1]+...+a[j]:x≤i≤j≤y}. 给定M个查询,程序必须输出这些查询的结果. 输入输出格式 输入格式: 输入文件的第一行包含整数N. 在第二行,N个数字跟随. 第三行包含整数M. M行跟在后面,其中第1行包含两个数字xi和yi. 输出格式: 您的程序应该输出M查询的结果,每一行一个查询. 思路: 我们做这道题首先应该想的,是两个