怒刷30道线段树、树状数组

HDU 1754 单点更新,区间查询最大值,水题……

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<bitset>
#define mem(a,b) memset(a,b,sizeof(a))
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define INF 1000000
#define maxn 1000010
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int Max[maxn],a[200005],n,m,i;
void pushup(int i)
{
    Max[i]=max(Max[i<<1],Max[i<<1|1]);
}
void build(int i,int l,int r)
{
    if(l==r)
    {
        Max[i]=a[l];
        return ;
    }
    int mid=(l+r)>>1;
    build(lson);build(rson);
    pushup(i);
}
void update(int i,int l,int r,int x,int v)
{
    if(l==r&&l==x)
    {
        Max[i]=v;
        return ;
    }
    int mid=(l+r)>>1;
    if(x<=mid) update(lson,x,v);
    else update(rson,x,v);
    pushup(i);
}
int query(int i,int l,int r,int L,int R)
{
    if(L<=l&&r<=R) return Max[i];
    int mid=(l+r)>>1,ans=0;
    if(L<=mid) ans=max(ans,query(lson,L,R));
    if(R>mid) ans=max(ans,query(rson,L,R));
    return ans;
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(i=1;i<=n;i++)
            scanf("%d",a+i);
        build(1,1,n);
        int x,y;
        char str[3];
        while(m--)
        {
            scanf("%s%d%d",str,&x,&y);
            if(str[0]=='Q')
                printf("%d\n",query(1,1,n,x,y));
            else update(1,1,n,x,y);
        }
    }
    return 0;
}

HDU 1698 区间更新,区间查询,lazy标记种类,水……

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<bitset>
#define mem(a,b) memset(a,b,sizeof(a))
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define INF 1000000
#define maxn 400010
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int sum[maxn],lazy[maxn],n,q;
void pushup(int i)
{
    sum[i]=sum[i<<1]+sum[i<<1|1];
}
void pushdown(int i,int l,int r)
{
    if(lazy[i])
    {
        int mid=(l+r)>>1;
        lazy[i<<1]=lazy[i<<1|1]=lazy[i];
        sum[i<<1]=(mid-l+1)*lazy[i<<1];
        sum[i<<1|1]=(r-mid)*lazy[i<<1|1];
        lazy[i]=0;
    }
}
void update(int i,int l,int r,int L,int R,int v)
{
    if(l==L&&r==R)
    {
        sum[i]=(r-l+1)*v;
        lazy[i]=v;
        return ;
    }
    int mid=(l+r)>>1;
    pushdown(i,l,r);
    if(R<=mid) update(lson,L,R,v);
    else if(L>mid) update(rson,L,R,v);
    else
    {
        update(lson,L,mid,v);
        update(rson,mid+1,R,v);
    }
    pushup(i);
}
void build(int i,int l,int r)
{
    if(l==r)
    {
        sum[i]=1;
        lazy[i]=1;
        return ;
    }
    sum[i]=lazy[i]=0;
    int mid=(l+r)>>1;
    build(lson);build(rson);
    pushup(i);
}
int main()
{
    int t;
    cin>>t;
    for(int i=1;i<=t;i++)
    {
        scanf("%d%d",&n,&q);
        build(1,1,n);
        int l,r,v;
        while(q--)
        {
            scanf("%d%d%d",&l,&r,&v);
            update(1,1,n,l,r,v);
        }
        printf("Case %d: The total value of the hook is %d.\n",i,sum[1]);
    }
    return 0;
}

怒刷30道线段树、树状数组

时间: 2024-10-06 06:07:47

怒刷30道线段树、树状数组的相关文章

线段树&amp;数状数组

线段树 单点修改,区间查询 #include<bits/stdc++.h> using namespace std; int n,q; long long num[1000010]; struct tree { int l,r; long long sum,max; }t[4000010]; void BuildTree(int,int,int); void Update(int,int,int,int,long long); long long Query(int,int,int,int,i

【刷题】【数据结构】【树状数组】【线段树】

1>数星星 (复制自他人博客) 由于题目中给的数据是按y轴排序,我们只需构建x轴的树状数组,也就是说我们只需统计星星i之前一共有多少个x坐标小于或等于Xi的星星,这个数值也就是星星i的等级 又因为树状数组无法处理下标为0的元素(会死循环),所以要把每个x坐标+1 #include<cstdio> #include<cstdlib> #include<algorithm> using namespace std; int max(int a,int b) { ret

树状数组 线段树

树状数组 树状数组的基本用途是维护序列的前缀和,相比前缀和数组,树状数组优势在于高效率的单点修改,单点增加(前缀和数组单点修改效率比较低) 因为树状数组的思想,原理还是很好理解的,就直接讲基本算法; 1 lowbit函数 关于lowbit这个函数,可能会有点难以理解,但其实你不理解也没关系,把模板背下来就好 根据任意正整数关于2的不重复次幂的唯一分解性质,例如十进制21用二进制表示为10101,其中等于1的位是第0,2,4(最右端是第0位)位,即21被二进制分解成\(2^4+2^2+2^0\);

Vijos P1066 弱弱的战壕【多解,线段树,暴力,树状数组】

弱弱的战壕 描述 永恒和mx正在玩一个即时战略游戏,名字嘛~~~~~~恕本人记性不好,忘了-_-b. mx在他的基地附近建立了n个战壕,每个战壕都是一个独立的作战单位,射程可以达到无限(“mx不赢定了?!?”永恒[email protected][email protected]). 但是,战壕有一个弱点,就是只能攻击它的左下方,说白了就是横纵坐标都不大于它的点(mx:“我的战壕为什么这么菜”ToT).这样,永恒就可以从别的地方进攻摧毁战壕,从而消灭mx的部队. 战壕都有一个保护范围,同它的攻击

[luogu P3801] 红色的幻想乡 [线段树][树状数组]

题目背景 蕾米莉亚的红雾异变失败后,很不甘心. 题目描述 经过上次失败后,蕾米莉亚决定再次发动红雾异变,但为了防止被灵梦退治,她决定将红雾以奇怪的阵势释放. 我们将幻想乡看做是一个n*m的方格地区,一开始没有任何一个地区被红雾遮盖.蕾米莉亚每次站在某一个地区上,向东南西北四个方向各发出一条无限长的红雾,可以影响到整行/整列,但不会影响到她所站的那个地区.如果两阵红雾碰撞,则会因为密度过大而沉降消失.灵梦察觉到了这次异变,决定去解决它.但在解决之前,灵梦想要了解一片范围红雾的密度.可以简述为两种操

【算法系列学习】线段树vs树状数组 单点修改,区间查询 [kuangbin带你飞]专题七 线段树 A - 敌兵布阵

https://vjudge.net/contest/66989#problem/A 单点修改,区间查询 方法一:线段树 http://www.cnblogs.com/kuangbin/archive/2011/08/15/2139834.html 1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 #include<cmath> 6 #

hdu1540 Tunnel Warfare 线段树/树状数组

During the War of Resistance Against Japan, tunnel warfare was carried out extensively in the vast areas of north China Plain. Generally speaking, villages connected by tunnels lay in a line. Except the two at the ends, every village was directly con

UVA 11990 ”Dynamic“ Inversion(线段树+树状数组)

[题目链接] UVA11990 [题目大意] 给出一个数列,每次删去一个数,求一个数删去之前整个数列的逆序对数. [题解] 一开始可以用树状数组统计出现的逆序对数量 对于每个删去的数,我们可以用线段树求出它在原序列中的逆序对贡献 在线段树的每个区间有序化数据,就可以二分查找出这个数在每个区间的位置, 这样就处理出了划分出的区间的贡献,先用答案减去这一部分 接下来考虑已经删去部分的容斥,我们发现只要对删去部分再做一次类似的操作, 将这一部分跟当前删去数求一次贡献就是刚才多减去的部分,将这部分的答案

士兵杀敌(四)(树状数组+线段树)

士兵杀敌(四) 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描述 南将军麾下有百万精兵,现已知共有M个士兵,编号为1~M,每次有任务的时候,总会有一批编号连在一起人请战(编号相近的人经常在一块,相互之间比较熟悉),最终他们获得的军功,也将会平分到每个人身上,这样,有时候,计算他们中的哪一个人到底有多少军功就是一个比较困难的事情,军师小工的任务就是在南将军询问他某个人的军功的时候,快速的报出此人的军功,请你编写一个程序来帮助小工吧. 假设起始时所有人的军功都是0. 输入