hdu4027(线段树)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4027

线段树功能:区间修改,区间求和。

分析:因为每个数至多开6次平方就变1了,所以对于每一段全为1的线段做lazy标志,若该条线段全为1时,就不用继续往下update,修改复杂度O(6*N),查询O(logN)。

#pragma comment(linker,"/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <stack>
#include <vector>
#include <set>
#include <map>
#define LL long long
#define mod 1000000007
#define inf 0x3f3f3f3f
#define N 100010
#define FILL(a,b) (memset(a,b,sizeof(a)))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
LL sum[N<<2],col[N<<2],a[N];
void Pushup(int rt)
{
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    col[rt]=col[rt<<1]&&col[rt<<1|1];
}
void build(int l,int r,int rt)
{
    col[rt]=0;
    if(l==r)
    {
        sum[rt]=a[l];
        return;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    Pushup(rt);
}
void update(int L,int R,int l,int r,int rt)
{
    if(l==r)
    {
        sum[rt]=(LL)sqrt(sum[rt]);
        if(sum[rt]==1)col[rt]=1;
        return;
    }
    int m=(l+r)>>1;
    if(L<=m&&!col[rt<<1])update(L,R,lson);
    if(m<R&&!col[rt<<1|1])update(L,R,rson);
    Pushup(rt);
}
LL query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R)
        return sum[rt];
    int m=(l+r)>>1;
    LL res=0;
    if(L<=m)res+=query(L,R,lson);
    if(m<R)res+=query(L,R,rson);
    return res;
}
int main()
{
    int n,m,cas=1;
    while(scanf("%d",&n)>0)
    {
        for(int i=1;i<=n;i++)scanf("%I64d",&a[i]);
        build(1,n,1);
        scanf("%d",&m);
        printf("Case #%d:\n",cas++);
        while(m--)
        {
            int op,x,y;
            scanf("%d%d%d",&op,&x,&y);
            if(x>y)swap(x,y);
            if(op==0)
            {
                update(x,y,1,n,1);
            }
            else
            {
                LL res=query(x,y,1,n,1);
                printf("%I64d\n",res);
            }
        }
        puts("");
    }
}

时间: 2024-08-05 15:24:27

hdu4027(线段树)的相关文章

HDU4027——线段树成段更新——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 eliminate the battleships. Each of the battleships can be marked a value of endurance. For every attack of our secret weapon, it

HDU4027(线段树单点更新区间)

Can you answer these queries? Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Submission(s): 11333    Accepted Submission(s): 2650 Problem Description A lot of battleships of evil are arranged in a line before

HDU4027 线段树

Can you answer these queries? Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Submission(s): 15314    Accepted Submission(s): 3590 Problem Description A lot of battleships of evil are arranged in a line before

HDU4027 Can you answer these queries 线段树区间求和+剪枝

给了你n,然后n个数字在一个数组中,接下来m个询问,每个询问三个数字 t,x,y,若t==0,那么修改区间[x,y]的每一个值,变为原来每个位置上的数 开根号取整,若t==1,那么对区间[x,y]求和 由于n,m,很大,所以树状数组铁定超时,若直接用线段树来做区间修改,那么也是超时,这类题目没别的方法了,静心剪枝,发现题目给的数据范围为2^63,有没有发现,2^63开根号 绝对不需要开10次,就能到1,到1以后就不需要再开了,意思就是若有某个区间[x,y]每一个点的值都为1时,这一段区间事实上是

hdu4027 Can you answer these queries?(线段树平方减少,区间求和)

转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4027 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 bat

线段树题目总结

一.单点更新 1.hdu1166 敌兵布阵:有N个兵营,每个兵营都给出了人数ai(下标从1开始),有四种命令,(1)"Addij",表示第i个营地增加j人.(2)"Sub i j",表示第i个营地减少j人.(3)"Query ij",查询第i个营地到第j个营地的总人数.(4)"End",表示命令结束.解题报告Here. 2.hdu1754 I Hate It:给你N个数,M个操作,操作分两类.(1)"QAB"

数据结构---线段树

线段树 转载请注明出处,谢谢!http://blog.csdn.net/metalseed/article/details/8039326  持续更新中···   一:线段树基本概念 1:概述 线段树,类似区间树,是一个完全二叉树,它在各个节点保存一条线段(数组中的一段子数组),主要用于高效解决连续区间的动态查询问题,由于二叉结构的特性,它基本能保持每个操作的复杂度为O(lgN)! 性质:父亲的区间是[a,b],(c=(a+b)/2)左儿子的区间是[a,c],右儿子的区间是[c+1,b],线段树

线段树总结 (转载 里面有扫描线类 还有NotOnlySuccess线段树大神的地址)

转载自:http://blog.csdn.net/shiqi_614/article/details/8228102 之前做了些线段树相关的题目,开学一段时间后,想着把它整理下,完成了大牛NotOnlySuccess的博文“完全版线段树”里的大部分题目,其博文地址Here,然后也加入了自己做过的一些题目.整理时,更新了之前的代码风格,不过旧的代码仍然保留着. 同样分成四类,不好归到前四类的都分到了其他.树状数组能做,线段树都能做(如果是内存限制例外),所以也有些树状数组的题目,会标示出来,并且放

线段树——转

  一:线段树基本概念 1:概述 线段树,类似区间树,是一个完全二叉树,它在各个节点保存一条线段(数组中的一段子数组),主要用于高效解决连续区间的动态查询问题,由于二叉结构的特性,它基本能保持每个操作的复杂度为O(lgN)! 性质:父亲的区间是[a,b],(c=(a+b)/2)左儿子的区间是[a,c],右儿子的区间是[c+1,b],线段树需要的空间为数组大小的四倍 2:基本操作(demo用的是查询区间最小值) 线段树的主要操作有: (1):线段树的构造 void build(int node,