程序设计竞赛
Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)
“你动规无力,图论不稳,数据结构松散,贪心迟钝,没一样像样的,就你还想和我同台竞技,做你的美梦!今天这场比赛,就是要让你知道你是多么的无能!!”
不训练,无以为战。有
n
项能力是ACM
竞赛要求的,训练则能提升,忽略则会荒废。
这 m 天,你能做到如何。
Input
第一行两个整数 n , m ,分别表示有 n 项能力要求,共有 m 天。
第二行 n 个整数,第 i 个整数 ai 表示第 i 项能力的数值。
接下来 m 行,每行开始先读入一个整数 si ,表明这是一次询问还是一次能力变化。
si=0 ,表明这是一次询问,然后读入两个整数 li,ri ,表示询问在 [li,ri] 区间中任选一段连续序列,这段序列中所有能力值之和最大能是多少。
si=1 ,表明这是一次能力变化,然后读入两个整数 xi,wi ,表示第 xi 项能力变为了 wi 。
1≤n,m≤100000,−10000≤ai≤10000,1≤li≤ri≤n,1≤xi≤n,−10000≤wi≤10000
Output
有多少询问就输出多少行,每行输出一个整数,作为对该询问的回答。
Sample input and output
Sample Input | Sample Output |
---|---|
4 4 1 2 3 4 0 1 3 1 3 -3 0 2 4 0 3 3 | 6 4 -3 |
3、 左儿子的maxx值
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
#define LL long long
const int N=100010;
const int MAX=1e9+7;
int n,m;
int a[N];
int ansl,ansr,anss,maxans;
inline void R(int &v)//读入、输出优化
{
v=0;
char ch=getchar();
int f=0;
while(!isdigit(ch)){if(ch=='-')f=1;ch=getchar();}
while(isdigit(ch)){v=(v<<3)+(v<<1)+ch-'0';ch=getchar();}
if(f) v=-v;
}
namespace ib {char b[100];}
inline void P(int x)
{
if(x==0) {putchar(48); return;}
if(x<0) {putchar('-'); x=-x;}
char *s=ib::b;
while(x) *(++s)=x%10, x/=10;
while(s!=ib::b) putchar((*(s--))+48);
}
struct Segtree
{
struct trie
{
int l,r,len;
int sum;
int maxl,maxr,maxx;
int lz;
}tree[N<<2];
void updata(int o)//线段树更新
{
int lo=o<<1,ro=o<<1|1;
tree[o].sum=tree[lo].sum+tree[ro].sum;
tree[o].maxl=max(tree[lo].maxl,tree[lo].sum+tree[ro].maxl);
tree[o].maxr=max(tree[ro].maxr,tree[ro].sum+tree[lo].maxr);
tree[o].maxx=tree[o].maxl;
tree[o].maxx=max(tree[o].maxx,tree[o].maxr);
tree[o].maxx=max(tree[o].maxx,tree[lo].maxx);
tree[o].maxx=max(tree[o].maxx,tree[ro].maxx);
tree[o].maxx=max(tree[o].maxx,tree[lo].maxr+tree[ro].maxl);
}
void build(int o,int l,int r)//建树
{
tree[o].sum=0;
tree[o].l=l;
tree[o].r=r;
tree[o].len=r-l+1;
if(l==r) {tree[o].sum=tree[o].maxl=tree[o].maxr=tree[o].maxx=a[l];return;}
int mid=(l+r)>>1;
build(o<<1,l,mid);
build(o<<1|1,mid+1,r);
updata(o);
}
void query(int o,int ql,int qr)//区间和
{
int l=tree[o].l,r=tree[o].r;
if(ql<=l&&qr>=r) //更新查找的区间答案(注意顺序)
{
ansl=max(ansl,anss+tree[o].maxl);
maxans=max(maxans,ansl);
maxans=max(maxans,ansr+tree[o].maxl);
maxans=max(maxans,tree[o].maxx);
ansr=max(ansr+tree[o].sum,tree[o].maxr);
maxans=max(maxans,ansr);
anss+=tree[o].sum;
return;
}
int mid=l+r>>1;
if(qr<=mid) query(o<<1,ql,qr);
if(ql>mid) query(o<<1|1,ql,qr);
if(ql<=mid&&qr>mid)
{
query(o<<1,ql,mid);
query(o<<1|1,mid+1,qr);
}
}
void change(int o,int q,int v)//单点修改
{
int l=tree[o].l,r=tree[o].r;
if(l==r) {tree[o].sum=v,tree[o].maxl=v,tree[o].maxr=v,tree[o].maxx=v;return;}
int mid=l+r>>1;
if(q<=mid) change(o<<1,q,v);
else change(o<<1|1,q,v);
updata(o);
}
}A;
int main()
{
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
int i,j;
R(n);R(m);
for(i=1;i<=n;++i) R(a[i]);
A.build(1,1,n);
for(i=1;i<=m;++i)
{
int x;
R(x);
if(x)
{
int q,v;
R(q);R(v);
A.change(1,q,v);
}
else
{
ansl=-MAX,ansr=-MAX,anss=0,maxans=-MAX;
int l,r;
R(l);R(r);
A.query(1,l,r);
P(maxans);
puts("");
}
}
return 0;
}
结语: