UESTC 1425 求任意区间的LIS 线段树区间更新区间查询
2013-09-24 15:14
525 查看
九野的博客,转载请注明出处:http://blog.csdn.net/acmmmm/article/details/11976621
Description
For a sequence S1,S2,...,SN, and a pair of integers (i, j), if 1 <= i <= j <= N and Si < Si+1 < Si+2 <...< Sj-1 < Sj, then the sequence Si,Si+1,...,Sjis a CIS (Continuous Increasing Subsequence). The longest CIS of a sequence is called theLCIS (Longest Continuous Increasing Subsequence).
In this problem, we will give you a sequence first, and then some “add” operations and some “query” operations. An add operation adds a value to each member in a specified interval. For a query operation, you should output the length of the LCIS of a specified
interval.
Input
The first line of the input is an integer T, which stands for the number of test cases you need to solve.Every test case begins with two integers N, Q, where N is the size of the sequence, and Q is the number of queries. S1,S2,...,SN are specified on the next line, and then Q queries follow. Every query begins with a character
‘a’ or ‘q’. ‘a’ is followed by three integers L, R, V, meaning that add V to members in the interval [L, R] (including L, R), and ‘q’ is followed by two integers L, R, meaning that you should output the length of the LCIS of interval [L, R].
T <= 10;
1 <= N, Q <= 100000;
1 <= L <= R <= N;
-10000 <= S1,S2,...,SN, V <= 10000.
Output
For every test case, you should output "Case #k:" on a single line first, where k indicates the case number and starts at 1. Then for every ‘q’ query, output the answer on a single line. See sample for more details.Sample Input
15 6
0 1 2 3 4
q 1 4
a 1 2 -10
a 1 1 -6
a 5 5 -4
q 2 3
q 4 4
Sample Output
Case #1:4
2
1
题意:n个数字m个询问
q l r //输出 [l,r] 区间的LIS
a l r temp // [l,r] 区间+ temp
#include <stdio.h> #include <string.h> #include <iostream> #include <math.h> #include <queue> #define N 201000 #define M 2000100 #define inf64 0x7ffffff #define inf 0x7ffffff #define ll int #define LL(x) (x<<1) #define RR(x) (x<<1|1) #define MID(x,y) (x+y)>>1 using namespace std; inline ll Min(ll a,ll b){return a>b?b:a;} inline ll Max(ll a,ll b){return a>b?a:b;} struct node { int lft,rht; int lmx,rmx,mx; int lval,rval,add; void fun(int tmp) { add+=tmp; lval+=tmp; rval+=tmp; } int len(){return rht-lft+1;} int mid(){return MID(lft,rht);} void init(){ lmx=rmx=mx=add=0; } }; int y ,n,m; struct Segtree { node tree[N*4]; void down(int ind) //向下更新,lazy, { if(tree[ind].add) { tree[LL(ind)].fun(tree[ind].add); tree[RR(ind)].fun(tree[ind].add); tree[ind].add=0; } } void up(int ind) //向上更新 { tree[ind].lmx=tree[LL(ind)].lmx; tree[ind].rmx=tree[RR(ind)].rmx; tree[ind].lval=tree[LL(ind)].lval; tree[ind].rval=tree[RR(ind)].rval; tree[ind].mx=max(tree[LL(ind)].mx,tree[RR(ind)].mx); if(tree[LL(ind)].rval<tree[RR(ind)].lval) { if(tree[LL(ind)].lmx==tree[LL(ind)].len()) tree[ind].lmx+=tree[RR(ind)].lmx; if(tree[RR(ind)].rmx==tree[RR(ind)].len()) tree[ind].rmx+=tree[LL(ind)].rmx; tree[ind].mx=max(tree[ind].mx,tree[LL(ind)].rmx+tree[RR(ind)].lmx); } tree[ind].mx=max(tree[ind].mx,max(tree[ind].lmx,tree[ind].rmx)); } void build(int lft,int rht,int ind) { tree[ind].lft=lft; tree[ind].rht=rht; tree[ind].init(); if(lft==rht) { tree[ind].lval=tree[ind].rval= y[lft]; //把y数组更新进来 tree[ind].lmx=tree[ind].rmx=tree[ind].mx=1; } else { int mid=tree[ind].mid(); build(lft,mid,LL(ind)); build(mid+1,rht,RR(ind)); up(ind); } } void updata(int st,int ed,int ind,int valu) //区间更新 { int lft=tree[ind].lft,rht=tree[ind].rht; if(st<=lft&&rht<=ed) tree[ind].fun(valu); else { down(ind); int mid=tree[ind].mid(); if(st<=mid) updata(st,ed,LL(ind),valu); if(ed> mid) updata(st,ed,RR(ind),valu); up(ind); } } int query(int st,int ed,int ind) //区间询问 { int lft=tree[ind].lft,rht=tree[ind].rht; if(st<=lft&&rht<=ed) return tree[ind].mx; else { down(ind); int mid=tree[ind].mid(); if(ed<=mid) return query(st,ed,LL(ind)); else if(st>mid) return query(st,ed,RR(ind)); else { int mid=tree[ind].mid(); int mx1=query(st,ed,LL(ind)); int mx2=query(st,ed,RR(ind)); int tmp1=0,tmp2=0; if(tree[LL(ind)].rval<tree[RR(ind)].lval) { tmp1=min(mid-st+1,tree[LL(ind)].rmx); tmp2=min(ed-mid,tree[RR(ind)].lmx); } return max(max(mx1,mx2),tmp1+tmp2); } } } }seg; //---------------线段树区间lazy更新,区间查询,LIS模版 --------------- int main(){ int n,a,b,i,T,Cas=1,que; char c; scanf("%d",&T); while(T--){ scanf("%d %d",&n,&que); for(i=1;i<=n;i++)scanf("%d",&y[i]); seg.build( 1, n, 1); printf("Case #%d:\n",Cas++); while(que--){ c=getchar(); while(c!='a' && c!='q') c=getchar(); scanf("%d %d",&a,&b); if(c=='q')printf("%d\n",seg.query(a,b,1)); else { scanf("%d",&i); seg.updata(a,b,1,i); } } } return 0; }
相关文章推荐
- 2015 UESTC 数据结构专题A题 秋实大哥与小朋友 线段树 区间更新,单点查询,离散化
- UESTC 1057 秋实大哥与花 线段树模板 区间更新+查询
- 线段树1(带懒惰标记的区间更新和整棵树的查询)
- HDU - 1754 I Hate It (线段树 单点更新区间查询)
- 线段树 HDU 4217 Data Structure? 单点更新 区间查询
- HDU1823 Luck and Love (二维线段树 + 单点更新 + 区间查询)
- Uva 11992 - Fast Matrix Operations题解(线段树区间更新+区间Set+Add,查询最大值,最小值,总和)
- 线段树(区间更新与区间查询)——Just a Hook ( HDU 1698 )
- HDU3966(树链剖分+线段树区间更新,单点查询)
- Necklace (线段树单点更新+区间查询+离线操作)
- hihocoder1070、1077线段树更新点查询区间
- HDU 1166 敌兵布阵-线段树-(单点更新,区间查询)
- ZOJ 5638——Prime Query——————【线段树区间更新,区间查询,单点更新】
- poj--3067 Japan(线段树+单点更新区间查询)
- 蓝桥杯_法训练—操作格子(线段树点更新与区间查询)
- HDU1698 线段树(区间更新区间查询)
- TSOJ1352 线段树区间更新+区间查询
- [模板]线段树的建树、查询、单点更新、区间更新
- poj3468 A Simple Problem with Integers(线段树,区间更新,区间和查询)
- hdu----(5023)A Corrupt Mayor's Performance Art(线段树区间更新以及区间查询)