luogu 3582 线段树

线段树内存下mx[k]的值是动态的1-i这个区间的贡献答案

实际上点存的就是区间答案,但用max是为了求最大区间答案(有可能虽然贡献被消除但后来有更大的贡献填补答案空缺)

#include<bits/stdc++.h>
#define rep(i,x,y) for(register int i=x;i<=y;i++)
#define dec(i,x,y) for(register int i=x;i>=y;i--)
#define LL long long
#define In freopen("7.in","r",stdin)
#define In2 freopen("8.in","r",stdin)
using namespace std;
const int N=1e6+50;
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();}
    while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;}
int n,m,w[N],f[N],mark[N],pre[N];
LL mx[N<<2],tag[N<<2],ans=0;
inline void pushup(int k){
    mx[k]=max(mx[k<<1],mx[k<<1|1]);}
inline void pushdown(int k,int l,int r,int mid){
    if(l==r) return;
    LL v=tag[k];tag[k]=0;
    tag[k<<1]+=v;mx[k<<1]+=v;
    tag[k<<1|1]+=v;mx[k<<1|1]+=v;}
inline void change(int k,int l,int r,int x,int y,LL d){
    if(x<=l&&r<=y){
        tag[k]+=d;mx[k]+=d;return;}
    int mid=(l+r)>>1;
    if(tag[k]) pushdown(k,l,r,mid);
    if(x<=mid) change(k<<1,l,mid,x,y,d);
    if(mid<y) change(k<<1|1,mid+1,r,x,y,d);
    pushup(k);
}
inline LL query(int k,int l,int r,int x,int y){
    if(x<=l&&r<=y) return mx[k];LL res=0;
    int mid=(l+r)>>1;if(tag[k])pushdown(k,l,r,mid);
    if(x<=mid) res=max(res,query(k<<1,l,mid,x,y));
    if(mid<y) res=max(res,query(k<<1|1,mid+1,r,x,y));
    return mx[k];}
int main(){
    n=read();m=read();
    rep(i,1,n) f[i]=read();
    rep(i,1,m) w[i]=read();
    rep(i,1,n) pre[i]=mark[f[i]],mark[f[i]]=i;

    rep(i,1,n){
        change(1,1,n,pre[i]+1,i,w[f[i]]);
        if(pre[i]) change(1,1,n,pre[pre[i]]+1,pre[i],-w[f[i]]);
        ans=max(ans,query(1,1,n,1,i));
    }
    printf("%lld\n",ans);return 0;
}

原文地址:https://www.cnblogs.com/asdic/p/9726990.html

时间: 2024-10-11 08:12:50

luogu 3582 线段树的相关文章

【luogu P3372 线段树1】模板

线段树的模板题 update区间修改,query区间求和 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #define ll long long 5 #define lson left, mid, rt<<1 6 #define rson mid+1, right, rt<<1|1 7 using namespace std; 8 const int maxn

1.1 线段树的基础操作

本篇对应的是luogu的线段树1 概况: 如下图就是一棵线段树,线段树上的每一个点记录的都是一个区间,所以线段树支持对于区间和点的动态操作,可以在线查询和更改区间上的最值,求和等 时间复杂度:O(n) 使用线段树的情况: 满足区间加法:已知左右两子树的全部信息,一定能够推出父节点 线段树维护的内容根据题目的要求而定 线段树的分类: 根据题目中对于查询和修改区间的不同要求,大致将线段树分为三类: problem1:单点修改,单点查询 problem2:区间修改,单点查询 problem3:区间修改

【原创】洛谷 LUOGU P3373 【模板】线段树2

P3373 [模板]线段树 2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含三个整数N.M.P,分别表示该数列数字的个数.操作的总个数和模数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含3或4个整数,表示一个操作,具体如下: 操作1: 格式:1 x y k 含义:将区间[x,y]内每个数乘上k 操作2: 格式:2 x

[Luogu] 可持久化线段树 1(主席树)

https://www.luogu.org/problemnew/show/P3834 #include<cstdio> #include<iostream> #include<algorithm> #include<cstring> using namespace std; const int maxn = 2e5 + 10; #define RR freopen("gg.in", "r", stdin) int n

luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树)(主席树)

luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树) 题目 #include<iostream> #include<cstdlib> #include<cstdio> #include<cmath> #include<cstring> #include<iomanip> #include<algorithm> #include<ctime> #include<queue> #inc

Luogu 45887 全村最好的嘤嘤刀(线段树 树状数组)

https://www.luogu.org/problemnew/show/T45887 题目背景 重阳节到了,我们最好的八重樱拥有全村最好的嘤嘤刀…… 题目描述 在绯玉丸力量的影响下,八重村成了一条长度为 nnn 的八重街,并且绯玉丸可以带着八重樱出现在街上的任意地点.而我们的八重樱则会在街上任意穿梭来获取某一地点上的嘤嘤嘤能量,用以升级她的嘤嘤刀. 在每个时刻,都会发生以下 333 个事件: 111 xxx valvalval 表示在 xxx 地点出现了携带着 valvalval 点嘤嘤嘤能

luogu 1712 区间(线段树+尺取法)

题意:给出n个区间,求选择一些区间,使得一个点被覆盖的次数超过m次,最小的花费.花费指的是选择的区间中最大长度减去最小长度. 坐标值这么大,n比较小,显然需要离散化,需要一个技巧,把区间转化为半开半闭区间,然后线段树的每一个节点表示一个半开半闭区间. 接着我们注意到需要求最小的花费,且这个花费只与选择的区间集合中的最大长度和最小长度有关. 这意味着如果最大长度和最小长度一定,我们显然是需要把中间长度的区间尽量的选择进去使答案不会变的更劣. 不妨把区间按长度排序,枚举每个最小长度区间,然后最大区间

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

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

【Luogu】P1607庙会班车Fair Shuttle(线段树+贪心)

我不会做贪心题啊--贪心题啊--题啊--啊-- 我真TM菜爆了啊-- 这题就像凌乱的yyy一样,把终点排序,终点相同的按起点排序.然后维护一个查询最大值的线段树.对于一个区间[l,r],如果这个区间已经有的最大值为s,那么这个区间最多还能装下c-s头奶牛. 当然奶牛数量没那么多的话我也是没有办法 最后说一句,奶牛到终点就下车了,可以给别的奶牛腾空间,不计入个数.所以奶牛在车上的区间为[l,r-1]. #include <cstdio> #include <iostream> #in