【Wannafly挑战赛10】D.小H的询问(线段树的区间合并)
2018-02-28 13:50
453 查看
记录一个菜逼的成长。。
题目链接
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
0 l r(1<=l<=r<=n),询问区间[l,r]中权值和最大的有效子区间的权值和,一个子区间被认为是有效的当且仅当这个子区间中没有两个相邻的偶数或者奇数。
1 x v(1<=x<=n,−109<=v<=109),将a[x]的值修改为v。
输入描述:
第一行读入两个正整数n,m(1<=n,m<=10^5)
第二行读入n个整数,第i个表示a[i](-10^9 <= a[i] <= 10^9)
接下来m行,每行三个数表示操作,描述见题目描述。
输出描述:
输出每个询问的答案。
可以说是模板题了吧。
先说结点的结构。
记录区间的左右边界的l,r;
记录区间[l,r]的所有数的和sum
记录在区间[l,r]里最左边的有效区间,即包含左端点的有效区间的值sl,和最右边的有效区间的值sr。
记录区间[l,r]里有效区间的最大值ans
重点在如何合并。
现在有两个区间[l1,r1],[l2,r2]
当ar1与al2不互为偶数或奇数时,
两区间可以合并。
此时合并后的区间[l1,r2]的sl为
max(sl1,sum1+sl2)
这里包含了两层意思。
如果区间[l1,r1]为有效区间,sum为区间和,max自然会取后值。
如果区间[l1,r1]不为有效区间,sum会被设为-INF,max自然会取前值。
同理sr=max(sr2,sum2+sr1)
ans=max(max(ans1,ans2),sr1+sl2)
反之两区间不可以合并时
sum被设为-INF,与合并时的操作相对应
sl=sl1,sr=sr2
ans=max(ans1,ans2)
题目链接
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
小H给你一个数组{a},要求支持以下两种操作:0 l r(1<=l<=r<=n),询问区间[l,r]中权值和最大的有效子区间的权值和,一个子区间被认为是有效的当且仅当这个子区间中没有两个相邻的偶数或者奇数。
1 x v(1<=x<=n,−109<=v<=109),将a[x]的值修改为v。
输入描述:
第一行读入两个正整数n,m(1<=n,m<=10^5)
第二行读入n个整数,第i个表示a[i](-10^9 <= a[i] <= 10^9)
接下来m行,每行三个数表示操作,描述见题目描述。
输出描述:
输出每个询问的答案。
分析
算是经典的线段树的区间合并。可以说是模板题了吧。
先说结点的结构。
记录区间的左右边界的l,r;
记录区间[l,r]的所有数的和sum
记录在区间[l,r]里最左边的有效区间,即包含左端点的有效区间的值sl,和最右边的有效区间的值sr。
记录区间[l,r]里有效区间的最大值ans
重点在如何合并。
现在有两个区间[l1,r1],[l2,r2]
当ar1与al2不互为偶数或奇数时,
两区间可以合并。
此时合并后的区间[l1,r2]的sl为
max(sl1,sum1+sl2)
这里包含了两层意思。
如果区间[l1,r1]为有效区间,sum为区间和,max自然会取后值。
如果区间[l1,r1]不为有效区间,sum会被设为-INF,max自然会取前值。
同理sr=max(sr2,sum2+sr1)
ans=max(max(ans1,ans2),sr1+sl2)
反之两区间不可以合并时
sum被设为-INF,与合并时的操作相对应
sl=sl1,sr=sr2
ans=max(ans1,ans2)
#include <bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair #define fi first #define se second #define cl(a,b) memset(a,b,sizeof(a)) #define clr clear() #define lson t<<1,l,mid #define rson t<<1|1,mid+1,r #define seglen(t) (node[t].r-node[t].l+1) typedef long long LL; typedef pair<LL,LL> PLL; typedef pair<int,int> PII; const LL INF = 0x3f3f3f3f; const int maxn = 100000 + 10; LL a[maxn]; struct Node{ int l,r; LL sl,sr; LL ans,sum; Node(){l = r = 0;sum = -INF * maxn;} Node operator + (const Node &ob)const { Node ret ; ret.l = l;ret.r = ob.r; if((a[r]^a[ob.l])&1) { ret.sum = sum + ob.sum; ret.sl = max(sl,sum + ob.sl); ret.sr = max(ob.sr,ob.sum + sr); ret.ans = max(max(ans,ob.ans),sr + ob.sl); } else { ret.sum = -INF * maxn; ret.sl = sl;ret.sr = ob.sr; ret.ans = max(ans,ob.ans); } return ret; } }node[maxn<<2]; void pushup(int t) { node[t] = node[t<<1] + node[t<<1|1]; } void build(int t,int l,int r) { node[t].l = l; node[t].r = r; node[t].sum = -INF * maxn; if (l == r) { node[t].sl = node[t].sr = node[t].ans = node[t].sum = a[l]; return ; } int mid = (l + r) >> 1; build(lson); build(rson); pushup(t); } void update(int t,int ind,LL v) { if(node[t].l == node[t].r) { node[t].sl = node[t].sr = node[t].ans = node[t].sum = v; return ; } int mid = (node[t].l + node[t].r) >> 1; if(ind <= mid)update(t<<1,ind,v); if(ind > mid)update(t<<1|1,ind,v); pushup(t); } Node query(int t,int l,int r) { if(node[t].l >= l && r >= node[t].r) { return node[t]; } int mid = (node[t].l + node[t].r) >> 1; if(l > mid)return query(t<<1|1,l,r); if(r <= mid)return query(t<<1,l,r); return query(t<<1,l,r) + query(t<<1|1,l,r); } int main() { int n,m; while(~scanf("%d%d",&n,&m)) { for (int i = 1; i <= n; i++) scanf("%lld",a+i); build(1,1,n); while(m--) { int ope,l,r; scanf("%d%d%d",&ope,&l,&r); if(ope) { a[l] = r; update(1,l,(LL)r); } else { Node ret = query(1,l,r); printf("%lld\n",ret.ans); } } } return 0; }
相关文章推荐
- Wannafly挑战赛10-D-小H的询问(线段树区间合并)
- [HDU 5316] Magician (线段树+单点更新+区间询问+区间合并)
- 线段树 (区间合并)
- HDU 3308 LCIS 线段树 区间合并 入门题
- hdu 4351 Digital root(线段树区间合并)
- [UESTC]Another LCIS[线段树][区间合并][成段修改]
- UVA-1400-"Ray, Pass me the dishes!"(线段树-区间合并)
- POJ 3667 & HDU 3308 & HDU 3397 线段树的区间合并
- 线段树区间合并 维护连续区间长度 模版(自己)
- Atlantis hdu 1542 线段树 扫面线 区间合并
- hdu 3308(线段树区间合并)
- HDU-3397 线段树+区间合并
- hdu 3308-线段树基本区间合并
- hdu 3397 Sequence operation(线段树,lazy,区间合并)
- Tunnel Warfare HDU - 1540 单点更新 区间合并 线段树
- hdu1540(线段树区间合并)
- SPOJ GSS1_Can you answer these queries I(线段树区间合并)
- 线段树--区间合并hdu--1540
- hdu1540 Tunnel Warfare 线段树区间合并
- 线段树 (区间合并)【p2894】[USACO08FEB]酒店Hotel