hdu 5172 GTY's gay friends(线段树最值)
2024-10-12 20:01:20
题意:
GTY有n个朋友,站成一排,每个人有一个特征值ai。
有m个询问。每次询问给两个数L,R。问你[L,R](即aL...aR)是否是1..(R-L+1)的一个全排列。
是输出YES,否则输出NO
思路:
先判断是否segma(a[L,R])是否等于(R-L)*(R-L+1)/2。
记录每一个ai上一次的位置pre[i]。
这样只要判断a[L]...a[R]中的每一个pre[i]是否都小于L即可。(这个方法太妙)
线段树区间求最大值。
*用map效率明显下降。
代码:
int const N = 1000005;
int n,m;
int a[N];
ll sum[N];
int pre[N];
int F[N<<4];
int lastPos[N]; void PushUp(int rt){
F[rt]=max( F[rt<<1],F[rt<<1|1] );
}
void build(int l,int r,int rt){
if(l==r){
F[rt]=pre[l];
return;
}
int m=(l+r)>>1;
build(lson);
build(rson);
PushUp(rt);
}
int query(int L,int R,int l,int r,int rt){
if(L<=l && r<=R){
return F[rt];
}
int m=(l+r)>>1;
int ret=0;
if(L<=m) ret=max( ret,query(L,R,lson) );
if(R>m) ret=max( ret,query(L,R,rson) );
return ret;
} int main(){ while(scanf("%d%d",&n,&m)!=EOF){
sum[0]=0;
rep(i,1,n){
scanf("%d",&a[i]);
sum[i]=sum[i-1]+a[i];
}
mem(lastPos,0);
rep(i,1,n){
pre[i]=lastPos[a[i]];
lastPos[a[i]]=i;
}
build(1,n,1); while(m--){
int L,R;
scanf("%d%d",&L,&R);
ll temp=(ll)1*(R-L+2)*(R-L+1)/2;
if( ((sum[R]-sum[L-1])==temp)&&query(L,R,1,n,1)<L ){
puts("YES");
}
else{
puts("NO");
}
}
} return 0;
}
最新文章
- 你真的会玩SQL吗?实用函数方法汇总
- Python黑帽编程2.2 数值类型
- Ubuntu Kylin 14.04下配置JDK1.8
- 实验二 简易版C语言文法
- django TEMPLATES
- Delphi常用系统函数总结
- 《objective-c基础教程》学习笔记(八)—— 拆分接口和实现
- Silverlight中使用MVVM:DataGrid中触发Button的Click事件
- MySQL各个版本区别
- c++ 钻石继承
- 对.NET的认识
- python的工作记录B
- VIM+qmake编译示例程序HelloQt出错问题的解决(文件名一定要使用.cpp,否则就会默认使用gcc编译,当然通不过)
- 飘逸的python - 一个最简单的服务器
- hihoCoder 1014trie树(字典树)
- JUnit java单元测试
- 【原创】mdk5宏定义的使用小结
- cadence元件放置方法
- springboot+mybatis+dubbo+aop日志终结篇
- Apache服务器中设置端口映射和反向代理的方法