数据结构(势能线段树)

https://www.luogu.com.cn/problem/P10516

第3题     数据结构 查看测评数据信息

给定两个长度为 n 的序列 a[i] 和 b[i]。有以下三种操作:

1. 给定区间 [l,r] 以及参数 k,t,把区间内满足 a[i]* b[i]<= k 的位置的 a[i] 和 b[i] 分别加上 t。

2. 给定 i 和 x,y,将 a[i] 改为 x,b[i] 改为 y。

3. 查询区间内每个位置 a[i]+b[i] 的和。

输入格式

 

第一行包含两个整数 n,m,分别表示该数列数字的个数和操作的总个数。

第二行包含 n 个用空格分隔的整数,其中第 i 个数字表示 a[i]。

第三行包含 n 个用空格分隔的整数,其中第 i 个数字表示 b[i]。

接下来 m 行每行包含 3 到 5 个整数,表示一个操作,具体如下:

1. 1 l r k t:将区间 [l,r] 进行一操作。

2. 2 i x y:将 a[i] 改为 x,b[i] 改为 y。

3. 3 l r:输出区间 [l,r] 内每个数的和。

1<= n,m<= 1e5,0<= a[i],b[i],k,t,x,y<=1e5

 

输出格式

 

若干行,每行表示操作 3 的答案。

 

输入/输出例子1

输入:

5 5

23 4 3 3 7

54 29 7 1 2

1 1 5 114 1

2 2 7 9

3 1 5

3 1 2

3 3 4

 

输出:

122

93

18

 

样例解释

 

第一次修改后,序列 a[i] 为:{23,4,4,4,8};序列 b[i] 为 {54,29,8,2,3}。

第二次修改后,序列 a[i] 为:{23,7,4,4,8};序列 b[i] 为 {54,9,8,2,3}。

 

 

势能线段树概念(重要)


 

本质上是一种区间暴力修改技术。

考虑普通的区修线段树,我们使用 lazytag 来记录区间修改信息,在访问到当前节点之后再将当前节点的 tag 下传。

然而,有很多信息是不好下传的(不满足交换或结合律),于是我们就无法使用 tag 来记录区修信息。但有的题目每一个操作都有潜在的操作次数上限,我们可以先判断该区间有没有需要操作的节点,有的话遍历到叶子节点进行修改,没有的话返回。

 

 

 

 

 

单调操作,区间查询,很容易想到线段树

操作二,三都是板子,我们关注一下操作一

分析一下操作一

看上去是区间修改,但是下放lazy_tag发现很难,对于修改也很难(不知具体改哪一个点),原因就是此操作不满足区间性(区间的每个值同时加减乘除等等吧)。所以考虑单点修改

由于每次操作完

a[i]*b[i] 都变成 (a[i]+t)*(b[i]+t)

我们化简。a[i]*b[i] + a[i]*t + b[i]*t + t*t

注意到最后一项,这样就说明这个值的增长是非常快的,操作次数不超过 sqrt(k) 就可以到上限

但是注意,这里 t不为0,才能增长,否则就是无意义的。

还有一点,要维护一个区间最小值,因为只有<=k的值才能进行修改。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+5;
 
struct node
{
    int Min, sum;
}tr[N];
int n, m, x, y, op, a[N], b[N], L, R, k, t;
void push_up(int id)
{
    tr[id].sum=tr[id*2].sum+tr[id*2+1].sum;
    tr[id].Min=min(tr[id*2].Min, tr[id*2+1].Min);
}
void build(int id, int L, int R)
{
    if (L==R)
    {
        tr[id].sum=a[L]+b[L];
        tr[id].Min=a[L]*b[L];
        return ;
    }
      
    int mid=(L+R)>>1;
    build(id*2, L, mid);
    build(id*2+1, mid+1, R);
      
    push_up(id);
}
void change(int id, int L, int R, int x, int y, int k, int t)
{
    if (tr[id].Min>k) return ;
    if (L==R)
    {
        a[L]+=t;
        b[L]+=t;
        tr[id].sum=a[L]+b[L];
        tr[id].Min=a[L]*b[L];
        return ;
    }
      
    int mid=(L+R)>>1, flag=1;
    if (x<=mid) change(id*2, L, mid, x, y, k, t);
    if (y>=mid+1) change(id*2+1, mid+1, R, x, y, k, t);
      
    push_up(id);
}
void change2(int id, int L, int R, int x, int v, int v2)
{
    if (L==R)
    {
        a[x]=v;
        b[x]=v2;
        tr[id].sum=a[L]+b[L];
        tr[id].Min=a[L]*b[L];
        return ;
    }
      
    int mid=(L+R)>>1;
    if (x<=mid) change2(id*2, L, mid, x, v, v2);
    else change2(id*2+1, mid+1, R, x, v, v2);
     
    push_up(id);
}
int ask(int id, int L, int R, int x, int y)
{
    if (x<=L && R<=y) return tr[id].sum;
      
    int mid=(L+R)>>1, res=0;
    if (x<=mid) res+=ask(id*2, L, mid, x, y);
    if (y>=mid+1) res+=ask(id*2+1, mid+1, R, x, y);
      
    return res;
}
signed main()
{
    scanf("%lld%lld", &n, &m);
    for (int i=1; i<=n; i++) scanf("%lld", &a[i]);
    for (int i=1; i<=n; i++) scanf("%lld", &b[i]);
    build(1, 1, n);
      
    while (m--)
    {
        scanf("%lld", &op);
        if (op==1)
        {
            scanf("%lld%lld%lld%lld", &L, &R, &k, &t);
            if (t==0) continue;
            change(1, 1, n, L, R, k, t);
        }
        else if (op==2)
        {
            scanf("%lld%lld%lld", &k, &L, &R);
            change2(1, 1, n, k, L, R);
        }
        else
        {
            scanf("%lld%lld", &L, &R);
            printf("%lld\n", ask(1, 1, n, L, R));
        }
    }
    return 0;
}

  

 

 

 

 

 

 

 

 

 

posted @   cn是大帅哥886  阅读(29)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示