您的位置:首页 > 其它

HDU 3308 LCIS

2015-11-28 18:33 393 查看
线段树区间合并

/* ***********************************************
Author        :Zhou Zhentao
Email         :774388357@qq.com
Created Time  :2015/11/28 9:05:25
File Name     :main.cpp
************************************************ */

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;

const int maxn=100000+10;
struct SegTree
{
int lsum,rsum,msum;
int lnum,rnum;
}segTree[4*maxn];
int T,N,Q;

void pushUp(int rt,int len)
{
//确定左边第一个数字
segTree[rt].lnum=segTree[2*rt].lnum;

//确定右边第一个数字
segTree[rt].rnum=segTree[2*rt+1].rnum;

//确定从左开始的最长连续上升的长度
if(segTree[2*rt].msum==len-len/2&&segTree[2*rt].rnum<segTree[2*rt+1].lnum)
segTree[rt].lsum=segTree[2*rt].lsum+segTree[2*rt+1].lsum;
else segTree[rt].lsum=segTree[2*rt].lsum;

//确定从右开始的最长连续上升的长度
if(segTree[2*rt+1].msum==len/2&&segTree[2*rt].rnum<segTree[2*rt+1].lnum)
segTree[rt].rsum=segTree[2*rt].rsum+segTree[2*rt+1].rsum;
else segTree[rt].rsum=segTree[2*rt+1].rsum;

//确定区间最长连续上升的长度
segTree[rt].msum=max(segTree[2*rt].msum,segTree[2*rt+1].msum);
if(segTree[2*rt].rnum<segTree[2*rt+1].lnum)
segTree[rt].msum=max(segTree[rt].msum,segTree[2*rt].rsum+segTree[2*rt+1].lsum);
}

void build(int l,int r,int rt)
{
if(l==r)
{
scanf("%d",&segTree[rt].lnum);
segTree[rt].rnum=segTree[rt].lnum;
segTree[rt].lsum=segTree[rt].rsum=segTree[rt].msum=1;
return ;
}

int m=(l+r)/2;
build(l,m,rt*2);
build(m+1,r,rt*2+1);

pushUp(rt,r-l+1);
}

void update(int p,int add,int l,int r,int rt)
{
if(l==r)
{
segTree[rt].lnum=add;
segTree[rt].rnum=add;
return;
}

int m=(l+r)/2;
if(p<=m) update(p,add,l,m,2*rt);
else update(p,add,m+1,r,2*rt+1);

pushUp(rt,r-l+1);
}

int quary(int L,int R,int l,int r,int rt)
{
if(L<=l&&R>=r)
{
return segTree[rt].msum;
}
int m=(l+r)/2;
if(R<=m) return quary(L,R,l,m,2*rt);
else if(L>=m+1) return quary(L,R,m+1,r,2*rt+1);
else
{
int Q1=quary(L,R,l,m,2*rt);
int Q2=quary(L,R,m+1,r,2*rt+1);

int ans=max(Q1,Q2);

int Min1=min(segTree[2*rt].rsum,m-L+1);
int Min2=min(segTree[2*rt+1].lsum,R-m);

if(segTree[2*rt].rnum<segTree[2*rt+1].lnum)
ans=max(ans,Min1+Min2);
return ans;
}

}

int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&N,&Q);

build(1,N,1);

for(int i=1;i<=Q;i++)
{
char op[5];
int x,y;
scanf("%s",op);

if(op[0]=='Q')
{
scanf("%d%d",&x,&y);
printf("%d\n", quary(x+1,y+1,1,N,1));
}

else if(op[0]=='U')
{
scanf("%d%d",&x,&y);
update(x+1,y,1,N,1);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: