杭电3308
来源:互联网 发布:数控车床编程操作方法 编辑:程序博客网 时间:2024/06/06 01:01
/*
杭电3308 LCIS
真是做题伤身呀,看了博客,写了一中午,wrong,最后
竟然错在了一个1上
这是一道区间合并题
有两种操作
U A B
第A个数改为B
Q A B
输出A B 之间最长连续递增子序列
这一题的难点重要在merge(区间合并上)
*/
杭电3308 LCIS
真是做题伤身呀,看了博客,写了一中午,wrong,最后
竟然错在了一个1上
这是一道区间合并题
有两种操作
U A B
第A个数改为B
Q A B
输出A B 之间最长连续递增子序列
这一题的难点重要在merge(区间合并上)
*/
#include<stdio.h>#include<algorithm>using namespace std;#define MAXN 110008typedef struct{ __int64 l,r,lmax,rmax,max;} T;/* l,r左右边界 lmax 记录以左边界为起点的最长连续递增子序列 rmax 记录以右边界为终点的最长连续递增子序列 max 此区间最长连续子序列*/T node[MAXN*4];__int64 S[MAXN];void merge(__int64 i){ node[i].max=max(node[2*i].max,node[2*i+1].max); //左孩子的右边界小于右孩子的左边界,二者合并,更新最大值 if(S[node[2*i].r]<S[node[2*i+1].l]) node[i].max=max(node[i].max,node[2*i].rmax+node[2*i+1].lmax); //如果左孩子连续递增,且左孩子的右边界小于右孩子的左边界,二者合并 //更新此节点的lmax if(node[2*i].max==node[2*i].r-node[2*i].l+1&&S[node[2*i].r]<S[node[2*i+1].l]) node[i].lmax=node[2*i].max+node[2*i+1].lmax; else node[i].lmax=node[2*i].lmax; //如果右孩子连续递增,且左孩子的右边界小于右孩子的左边界,二者合并 //更新此节点的rmax, if(node[2*i+1].max==node[2*i+1].r-node[2*i+1].l+1&&S[node[2*i].r]<S[node[2*i+1].l]) node[i].rmax=node[2*i+1].max+node[2*i].rmax; else node[i].rmax=node[2*i+1].rmax;}//merge函数区间合并void Build_tree(__int64 i,__int64 l,__int64 r){ node[i].l=l;node[i].r=r; if(l==r){ node[i].max=node[i].lmax=node[i].rmax=1; return ; } __int64 mid=(l+r)/2; Build_tree(2*i,l,mid);Build_tree(2*i+1,mid+1,r); merge(i);}__int64 Qurry(__int64 i,__int64 l,__int64 r){ if(node[i].l==l&&node[i].r==r) return node[i].max; __int64 mid=(node[i].l+node[i].r)/2; if(r<=mid)return Qurry(2*i,l,r); else if(l>mid) return Qurry(2*i+1,l,r); //以上的查询都很容易理解,以下跨区间查询 else{ __int64 k,ll,rr; k=max(Qurry(2*i,l,mid),Qurry(2*i+1,mid+1,r)); if(S[mid]>=S[mid+1])return k;//这两个区间不能合并 ll=node[2*i].rmax>mid-l+1?mid-l+1:node[2*i].rmax; rr=node[2*i+1].lmax>r-mid?r-mid:node[2*i+1].lmax; //可以合并 return max(k,ll+rr); }}void Update(__int64 i,__int64 s){ if(node[i].l==s&&node[i].r==s)return ; __int64 mid=(node[i].l+node[i].r)/2; if(s<=mid) Update(2*i,s); else Update(2*i+1,s); merge(i);}int main(){ __int64 t,n,m,i; scanf("%I64d",&t); while(t--){ scanf("%I64d%I64d",&n,&m); for(i=0;i<n;i++)scanf("%I64d",&S[i]); Build_tree(1,0,n-1); char str[3]; __int64 x,y; for(i=0;i<m;i++){ scanf("%s%I64d%I64d",str,&x,&y); if(str[0]=='U'){S[x]=y;Update(1,x);} if(str[0]=='Q')printf("%I64d\n",Qurry(1,x,y)); } }}
- 杭电3308
- 杭电
- 杭电
- 杭电
- 杭电 1234 和 杭电 2115
- 杭电2056之Rectangles 杭电
- 杭电ACM1061Rightmost Digit
- 杭电2099 7.11
- 杭电ACM 1003
- 杭电 ACM 2016
- 杭电ACM1466
- 杭电ACM1003
- 杭电ACM1225
- 杭电ACM2023
- 杭电ACM2602
- 杭电ACM2955
- 杭电ACM3198
- 杭电ACM2028 求教
- 一次Avira小红伞误删文件
- 第四周项目
- AfxMessageBox和MessageBox区别
- Yii中的layouts使用(header,footer的使用方式)
- 可以点歌的微信公共账号
- 杭电3308
- Java Date 和 Calendar
- 俩组php面试题(对于面试的有用哦)
- CUGBACM11级专题训练之排序解题报告
- 皮肤检测与克服光线影响的连通域寻找
- HDU1213 How Many Tables(简单的并查集)
- spring mvc随笔
- 2013腾讯编程马拉松初赛第一场(3月21日)小Q系列故事——电梯里的爱情
- amq 源码分析之demo分析1