随笔 - 58,  文章 - 0,  评论 - 4,  阅读 - 3296

一、题目描述:

  有一段长度为 n 的序列,会进行 m 次操作,有两种操作。

    1 l r :求区间 l~r 的最大子段和 。

    2 p x :将第 p 个数的值修改为 x

  数据范围:1n5×105,1m105


 二、解题思路:

  其实是比较板子的线段树题,只是在各个题中学到了两个线段树策略:

    1: maxl,maxr , push_up

    2:

  所以还是写个博客纪念纪念一下吧!


 三、完整代码:

  :

复制代码
  1 #include<iostream>
  2 #define N 500010
  3 #define ls(p) p<<1
  4 #define rs(p) p<<1|1
  5 using namespace std;
  6 int k,x,y,n,m,a[N];
  7 struct Seg_tree{
  8     int mx,ml,mr,sum;
  9 }t[N*4];
 10 void push_up(int p)
 11 {
 12     t[p].mx=0;t[p].sum=t[ls(p)].sum+t[rs(p)].sum;
 13     t[p].ml=max(t[ls(p)].ml,t[ls(p)].sum+t[rs(p)].ml);
 14     t[p].mr=max(t[rs(p)].mr,t[rs(p)].sum+t[ls(p)].mr);
 15     if(t[ls(p)].mr>=0)    t[p].mx+=t[ls(p)].mr;
 16     if(t[rs(p)].ml>=0)    t[p].mx+=t[rs(p)].ml;
 17     if(t[ls(p)].mr<0&&t[rs(p)].ml<0)
 18         t[p].mx=max(t[ls(p)].mr,t[rs(p)].ml);
 19     t[p].mx=max(t[p].mx,max(t[ls(p)].mx,t[rs(p)].mx));
 20 }
 21 void build(int p,int l,int r)
 22 {
 23     if(l==r)
 24     {
 25         t[p].ml=t[p].mr=a[l];
 26         t[p].mx=t[p].sum=a[l];
 27         return ;
 28     }
 29     int mid=(l+r)>>1;
 30     build(ls(p),l,mid);
 31     build(rs(p),mid+1,r);
 32     push_up(p);
 33 }
 34 void update(int p,int l,int r,int x,int val)
 35 {
 36     if(l==r)
 37     {
 38         t[p].ml=t[p].mr=val;
 39         t[p].mx=t[p].sum=val;
 40         return ;
 41     }
 42     int mid=(l+r)>>1;
 43     if(x<=mid)    update(ls(p),l,mid,x,val);
 44     if(x>mid)    update(rs(p),mid+1,r,x,val);
 45     push_up(p);
 46 }
 47 int query(int p,int l,int r,int nl,int nr,int f)
 48 {
 49     if(l>nr||r<nl)
 50     {
 51         if(f==3)    return 0;
 52         else     return -1e9;
 53     }
 54     int mid=(l+r)>>1,ans=0;
 55     if(nl<=l&&r<=nr)
 56     {
 57         if(f==0)    return t[p].ml;
 58         if(f==1)    return t[p].mr;
 59         if(f==2)    return t[p].mx;
 60         if(f==3)    return t[p].sum;
 61     }
 62     if(f==3)
 63     {
 64         ans+=query(ls(p),l,mid,nl,nr,3);
 65         ans+=query(rs(p),mid+1,r,nl,nr,3);
 66         return ans;
 67     }
 68     if(f==0)
 69     {
 70         ans+=query(ls(p),l,mid,nl,nr,3);
 71         ans+=query(rs(p),mid+1,r,nl,nr,0);
 72         ans=max(ans,query(ls(p),l,mid,nl,nr,0));
 73         return ans;
 74     }
 75     if(f==1)
 76     {
 77         ans+=query(ls(p),l,mid,nl,nr,1);
 78         ans+=query(rs(p),mid+1,r,nl,nr,3);
 79         ans=max(ans,query(rs(p),mid+1,r,nl,nr,1));
 80     }
 81     if(f==2)
 82     {
 83         int t1=query(ls(p),l,mid,nl,nr,1);
 84         int t2=query(rs(p),mid+1,r,nl,nr,0);    
 85         if(t1>=0)    ans+=t1;
 86         if(t2>=0)    ans+=t2;
 87         if(t1<0&&t2<0)    ans=max(t1,t2);
 88         ans=max(ans,query(ls(p),l,mid,nl,nr,2));
 89         ans=max(ans,query(rs(p),mid+1,r,nl,nr,2));
 90     }
 91     return ans;
 92 }
 93 int main()
 94 {
 95     ios::sync_with_stdio(false);
 96     cin.tie(0);cout.tie(0); 
 97     cin>>n>>m;
 98     for(int i=1;i<=n;i++)
 99         cin>>a[i];
100     build(1,1,n);
101     for(int i=1;i<=m;i++)
102     {
103         cin>>k>>x>>y;
104         if(k==2) update(1,1,n,x,y);
105         if(k==1)
106         {
107             if(x>y)    swap(x,y);
108             cout<<query(1,1,n,x,y,2)<<'\n';
109         }
110     }
111     return 0;
112 }
复制代码

  :

复制代码
 1 #include<iostream>
 2 #define N 500010
 3 using namespace std;
 4 int k,x,y,n,m,a[N];
 5 struct Seg{
 6     int mx,ml,mr,sum;
 7 }t[N*4];
 8 void push_up(Seg &p,Seg lson,Seg rson)
 9 {
10     p.mx=0;p.sum=lson.sum+rson.sum;
11     p.ml=max(lson.ml,lson.sum+rson.ml);
12     p.mr=max(rson.mr,rson.sum+lson.mr);
13     if(lson.mr>=0)    p.mx+=lson.mr;
14     if(rson.ml>=0)    p.mx+=rson.ml;
15     if(lson.mr<0&&rson.ml<0)
16         p.mx=max(lson.mr,rson.ml);
17     p.mx=max(p.mx,max(lson.mx,rson.mx));
18 }
19 void build(int p,int l,int r)
20 {
21     if(l==r)
22     {
23         t[p].ml=t[p].mr=a[l];
24         t[p].mx=t[p].sum=a[l];
25         return ;
26     }
27     int mid=(l+r)>>1;
28     build(p<<1,l,mid);
29     build(p<<1|1,mid+1,r);
30     push_up(t[p],t[p<<1],t[p<<1|1]);
31 }
32 void update(int p,int l,int r,int x,int val)
33 {
34     if(l==r)
35     {
36         t[p].ml=t[p].mr=val;
37         t[p].mx=t[p].sum=val;
38         return ;
39     }
40     int mid=(l+r)>>1;
41     if(x<=mid)    update(p<<1,l,mid,x,val);
42     if(x>mid)    update(p<<1|1,mid+1,r,x,val);
43     push_up(t[p],t[p<<1],t[p<<1|1]);
44 }
45 Seg query(int p,int l,int r,int nl,int nr)
46 {
47     if(nl<=l&&r<=nr)    return t[p];
48     int mid=(l+r)>>1;    Seg ans,t1,t2;
49     if(nr<=mid)    return query(p<<1,l,mid,nl,nr);
50     if(nl>mid)    return query(p<<1|1,mid+1,r,nl,nr);
51     t1=query(p<<1,l,mid,nl,nr);
52     t2=query(p<<1|1,mid+1,r,nl,nr);
53     push_up(ans,t1,t2);    return ans;
54 }
55 int main()
56 {
57     ios::sync_with_stdio(false);
58     cin.tie(0);cout.tie(0); 
59     cin>>n>>m;
60     for(int i=1;i<=n;i++)
61         cin>>a[i];
62     build(1,1,n);
63     for(int i=1;i<=m;i++)
64     {
65         cin>>k>>x>>y;
66         if(k==2) update(1,1,n,x,y);
67         if(k==1)
68         {
69             if(x>y)    swap(x,y);
70             cout<<query(1,1,n,x,y).mx<<'\n';
71         }
72     }
73     return 0;
74 }
复制代码

四、写题心得:

  没有心得。加油!拜拜!UKE  orz

posted on   trh0630  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】

< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5
点击右上角即可分享
微信分享提示