【NOIP2017模拟8.8A组】Trip(trip)
来源:互联网 发布:bing词典mac 编辑:程序博客网 时间:2024/06/05 15:30
Description
多年之后,worldwideD厌倦竞争,隐居山林。 他的家乡开始发展起了旅游业,在一条很长的主干道上,有N个旅游景点,按顺序编号为1到N。根据游客们网上的评分,第i个景点有一个评估值a[i],为了区分开不同的景点,评估值是两两不同的。 今天有M组游客前来旅游,第i组游客选择遍历景点Li到景点Ri这一段路。他们搜到Li到Ri的所有评估值,如果对于景点j(Li≤j≤Ri),不存在景点x(Li≤x<j)满足a[x]>a[j]或不存在景点y(j<y≤Ri)满足a[y]>a[j],那么他们会进入景点j。 现在worldwideD想知道,每组游客会去多少个景点。
Input
第一行两个整数N,M,意义见题面。
接下来一行N个整数,第i个是a[i],意义见题面。
接下来M行,第i行两个整数Li,Ri,意义见题目。
Output
M行,第i行表示第i组游客去的景点个数。
Sample Input
6 4
3 1 7 4 5 2
1 5
2 5
2 6
4 6
Sample Output
3
3
4
3
Data Constraint
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
题解
先考虑按照a的值构造一棵笛卡尔树,对于一个询问l,r答案就是他们的lca到他们这两条链中到l链的每一个父亲的左儿子个数以及到r那边的右儿子个数
为什么这样做是对的呢?事实上对答案有贡献的并不是那个树节点对应的序列中的位置,如果这个点在序列中的位置在[l,r]外,那么一定有另一个在[l,r]中的点可以满足题目的要求
那么我们可以tarjan求lca,单调栈构造笛卡尔树来O(n)解决这个问题
贴代码
#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<cmath>#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;const int maxn=1000005;int a[maxn],fi[2*maxn],next[2*maxn],dui[2*maxn],sc[2*maxn],st[maxn*2],hc[maxn*2];int fa[maxn],da[maxn],son[maxn][3],zu[maxn],yo[maxn];int go[maxn][4];bool bz[maxn];int i,j,k,l,n,m,x,y,ans,p,root;bool b1;int read(){ int x=0,sig=1; char c; for (c=getchar();c<'0' || c>'9';c=getchar()) if (c=='-') sig=-1; for (;c>='0' && c<='9';c=getchar()) x=x*10+c-48; return x*sig;}void write(int x){ if (!x) putchar('0');else { char s[10]; int i,j=0; for (;x>0;x/=10) s[j++]=x%10; for (i=j-1;i>=0;i--) putchar(s[i]+48); } putchar('\n');}void add(int x,int y){ if (!fi[x]){ fi[x]=++l; dui[l]=y; sc[x]=l; } else{ next[sc[x]]=++l; dui[l]=y; sc[x]=l; } hc[l]=i;}int getfather(int x){ if (fa[x]==x) return x; else fa[x]=getfather(fa[x]); return fa[x];}void dfs(int x){ fa[x]=x; bz[x]=true; p=fi[x]; if (da[x]>0){ zu[x]=zu[da[x]]; yo[x]=yo[da[x]]; if (son[da[x]][1]==x) zu[x]++; else yo[x]++; } while (p){ if (bz[dui[p]]==true) go[hc[p]][3]=getfather(dui[p]); p=next[p]; } if (son[x][1]) dfs(son[x][1]); if (son[x][2]) dfs(son[x][2]); fa[x]=da[x];}int main(){// freopen("t3.in","r",stdin); freopen("trip.in","r",stdin); freopen("trip.out","w",stdout); scanf("%d%d",&n,&m); fo(i,1,n) a[i]=read(); fo(i,1,m) { go[i][1]=read(); go[i][2]=read(); add(go[i][1],go[i][2]); add(go[i][2],go[i][1]); } l=0; fo(i,1,n){ b1=false; while (l>0 && a[i]>a[st[l]]) { l--; b1=true; } if (b1){ da[i]=da[st[l+1]]; da[st[l+1]]=da[i]; son[da[i]][2]=i; son[i][1]=st[l+1]; da[st[l+1]]=i; } else { son[st[l]][2]=i; da[i]=st[l]; } st[++l]=i; if (l==1) root=i; } dfs(root); fo(i,1,m){ ans=-zu[go[i][3]]+zu[go[i][1]]-yo[go[i][3]]+yo[go[i][2]]+1; write(ans); } return 0;}
阅读全文
0 0
- 【NOIP2017模拟8.8A组】Trip(trip)
- Trip(trip) 【NOIP2017模拟8.8A组】
- JZOJ 5246. 【NOIP2017模拟8.8A组】Trip(trip)
- 【NOIP2017模拟8.8A组】Trip
- 【JZOJ5246】【NOIP2017模拟8.8A组】Trip
- jzoj5246. 【NOIP2017模拟8.8A组】Trip(trip) 笛卡尔数/二维偏序
- 【jzoj5246】【NOIP2017模拟8.8A组】【Trip】【笛卡尔树】【tarjan-lca】
- Trip
- Trip
- A. Business trip
- A. Trip For Meal
- A. Trip For Meal
- ★【模拟退火】Texas Trip
- 【NOIP2017模拟8.8A组】Competing Souls
- JZOJ5244. 【NOIP2017模拟8.8A组】Daydreamin
- 【JZOJ5244】【NOIP2017模拟8.8A组】Daydreamin
- A Trip To Deep Learning
- Codeforces Round #441 (Div. 2)A. Trip For Meal模拟水题
- hdu6081 度度熊的王国战略(并查集处理连通图问题)
- php 二维数组去重
- 关于Link Cut Tree
- 阿里编程测验
- 《Python基础教程》学习笔记——字符串
- 【NOIP2017模拟8.8A组】Trip(trip)
- Android 7.0解决抓取不到https请求的问题
- Django学习笔记10-URL的名称空间
- 注意多个实体类放进list的问题
- C语言结构体
- POI给合并的单元格设置边框
- 从共享征信黑名单开始:LinkEye想打造基于区块链的征信联盟
- MyEclipse使用总结——MyEclipse10安装SVN插件(转)
- HideInInspector SerializeField