Trip
来源:互联网 发布:文本压缩算法 编辑:程序博客网 时间:2024/05/16 12:12
Trip
Time Limits: 1500 ms Memory Limits: 262144 KB
题目大意
给定一个数列a[1..n]
输入
第一行两个整数n,m。
接下来一行n个整数,第i个是a[i]。
接下来m行,第i行两个整数Li,Ri。
输出
m行,第i行表示第i组游客去的景点个数。
样例
Input
6 43 1 7 4 5 21 52 52 64 6
Sample Output
3343
数据范围
30%:N,M≤5,000
60%:N,M≤100,000
100%:N,M≤1,000,000 0≤|a[i]|≤1,000,000,000 1≤Li≤Ri≤N
提示
第一组游客选择路段的景点评估值序列为[3,1,7,4,5],其中3,7,5满足条件
第二组游客选择路段的景点评估值序列为[1,7,4,5],其中1,7,5满足条件
第三组游客选择路段的景点评估值序列为[1,7,4,5,2],其中3,7,5,2满足条件
第四组游客选择路段的景点评估值序列为[4,5,2],其中4,5,2满足条件
本题数据规模较大,请注意您的常数造成的影响。
解题思路
60%
考虑a[i]能对那些期间有贡献
我们找出两个位置j,k其中
那么我们正着反着两次去扫,拿正着的说,反着的反之:
i从小到大扫,相应求出j,a[i]能对
当i扫到i+1时,r=i的区间就会作废,那么直接求l上的值,计入答案就好了
由于这种方法,区间最大值会计算两次,最后-1就行
O(nlogn)
100%
建棵大根笛卡尔树:
也就是说树上的所有节点x满足x的下标大于左子树中所有节点的下标,小于所有右子树节点的下标,x的权值小于子树所有节点的权值
O(n)法:
假设当前子树代表区间[h,t],那么这棵子树的根节点x一定是区间[h,t]中权值最大的位置,它的左节点l是区间[h,x)中最大的比a[x]小的位置,右节点r同理
先找连向左节点的边:
因为一个点向左连边只可能连向它左边比它小的最大数位置,从1到n扫过去,维护一个栈,从栈底到栈顶数呈上升,扫到i时,将a[i]丢进栈,把小于a[i]的位置弹栈,左后弹栈的位置即为小于a[i]且最大的位置,i认它为左节点
右节点的反过来找
void maketree(){ a[0]=1000000001;sta[0]=0;top=0; for(int i=1;i<=n;i++){ if(a[sta[top]]<a[i]){ while(a[sta[top]]<a[i])top--; fa[sta[top+1]]=i;son[i][0]=sta[top+1]; }sta[++top]=i; }top=0; for(int i=n;i;i--){ if(a[sta[top]]<a[i]){ while(a[sta[top]]<a[i])top--; fa[sta[top+1]]=i;son[i][1]=sta[top+1]; }sta[++top]=i; } for(root=1;fa[root]!=0;root=fa[root]);}
对于区间[l,r],最大值的位置就是l和r的lca,那么我们要求的是[l,r]中在路径(l,r)中的个数:1.lca 2.路径(l,lca)不包括lca为左节点 3.(r,lca)不包括lca为右节点
用个前缀和维护就好了
建树
tarjanlca
询问
总共是
但是怕tarjanlca会爆栈,又懒得打人工栈,换用了链剖lca,复杂度远小于
code:
#include<cstring>#include<cstdio>#define N 1001001using namespace std;int sta[N],a[N],n,m,fa[N],son[N][2],firx[N],firy[N],v[N],top,que[N],head,tail,rv[N],lv[N],root,Top[N],heavy[N],deep[N],siz[N];inline int read(){ int x=0,sig=1;char c;for(;(c=getchar())<'0' || c>'9';)if(c=='-')sig=-1; for (;c>='0' && c<='9';c=getchar())x=(x<<1)+(x<<3)+c-48;return x*sig;}inline void write(int x){ int top=0;char ch[10];for(;x;x/=10)ch[++top]=x%10+48; if(!top)ch[top=1]='0';while(top)putchar(ch[top--]); putchar('\n');}inline void maketree(){ a[0]=1000000001;sta[0]=0;top=0; for(int i=1;i<=n;i++){ if(a[sta[top]]<a[i]){ while(a[sta[top]]<a[i])top--; fa[sta[top+1]]=i;son[i][0]=sta[top+1];lv[sta[top+1]]=1; }sta[++top]=i; }top=0; for(int i=n;i;i--){ if(a[sta[top]]<a[i]){ while(a[sta[top]]<a[i])top--; fa[sta[top+1]]=i;son[i][1]=sta[top+1];rv[sta[top+1]]=1; }sta[++top]=i; } for(root=1;fa[root]!=0;root=fa[root]);rv[root]=1;}inline void makelink(){ for(head=0,siz[que[tail=1]=root]=1,deep[root]=1;head!=tail;){ head++;int now=que[head],l=son[now][0],r=son[now][1]; if(l)rv[l]+=rv[now],lv[l]+=lv[now],siz[que[++tail]=l]=1,deep[l]=deep[now]+1; if(r)rv[r]+=rv[now],lv[r]+=lv[now],siz[que[++tail]=r]=1,deep[r]=deep[now]+1; } for(int i=tail;i;i--){ int x=que[i]; siz[x]+=siz[son[x][0]]+siz[son[x][1]]; if(son[x][0] && (!son[x][1] || siz[son[x][0]]>=siz[son[x][1]]))heavy[x]=son[x][0]; else if(son[x][1])heavy[x]=son[x][1]; } for(head=0,Top[que[tail=1]=root]=root;head!=tail;){ head++;int now=que[head],l=son[now][0],r=son[now][1]; if(l && l==heavy[now])Top[que[++tail]=l]=Top[now];else if(l)Top[que[++tail]=l]=l; if(r && r==heavy[now])Top[que[++tail]=r]=Top[now];else if(r)Top[que[++tail]=r]=r; }}int main(){ freopen("trip.in","r",stdin); freopen("trip.out","w",stdout); n=read();m=read(); for(int i=1;i<=n;i++)a[i]=read(); maketree();makelink(); for(int i=1,x,y;i<=m;i++){ x=read(),y=read(); int lca; for(int x_=x,y_=y;;){ if(Top[x_]==Top[y_]){if(deep[x_]>deep[y_])lca=y_;else lca=x_;break;} if(deep[Top[x_]]>deep[Top[y_]])x_=fa[Top[x_]];else y_=fa[Top[y_]]; } write(1+rv[y]-rv[lca]+lv[x]-lv[lca]); } fclose(stdin);fclose(stdout); return 0;}
- Trip
- Trip
- HK Trip
- Road trip
- TRIP BOOK
- The trip
- The Trip
- Walmart trip
- Great Trip
- poj3301Texas Trip
- Ant Trip
- poj1934 Trip
- The Trip
- hdu2425Hiking Trip
- Ant Trip
- Ant Trip
- poj1734Sightseeing Trip
- hdu3018Ant Trip
- linux启动流程图
- [第六季]5.文档元素的隐藏与显示
- 几句话解释配置./configure --prefix的作用
- P1379 八数码难题
- CF798D:Mike and distribution(思维 )^
- Trip
- (转载)spring3和spring4的一些需要注意的地方
- 分数拆分
- T-SQL和安全机制
- EA&UML日拱一卒-活动图::Variable Actions(续)
- HDU 6090 计算权值 思维题
- STM8L051x SPI Master
- 算法竞赛入门经典习题3-6 &3-7 进制转换
- C语言判断二叉树的子树