noip2012 开车旅行 set+倍增
来源:互联网 发布:2017网络教育专升本 编辑:程序博客网 时间:2024/05/04 08:24
因为要快速查找向后跳应该是哪一个点,所以用set,迭代器左右晃一下查找最接近的两个元素(P选手是不是只能用平衡树~)。然后用倍增记录i节点跳2^j步后,A和B分别走的距离。具体的细节和统计答案也需要注意。
#include<iostream>#include<cstdio>#include<cmath>#include<set>#include<map>#include<algorithm>#define maxn 100005#define LL long longusing namespace std;set<LL> Set;set<LL>::iterator it,pre,nxt;map<LL,int> id;int fa[maxn][20];int tt[maxn];LL dis[maxn][20][2];LL dp[maxn][2];void read(LL &a){ a=0;LL f=1; char c=getchar(); while(c<'0'||c>'9') { if(c=='-')f=-1; c=getchar(); } while(c>='0'&&c<='9') { a*=10;a+=c-'0'; c=getchar(); }a*=f;}LL H[maxn];int n,cnt;LL inf=1e10;struct str{ int id;LL key,num;}sor[6];bool cid(str A,str B){ if(A.key!=B.key) return A.key<B.key; return A.num<B.num;}void init(){ scanf("%d",&n); for(int i=1;i<=n;i++) { read(H[i]); Set.insert(H[i]); id[H[i]]=i; } for(int i=1;i<n;i++) { nxt=pre=it=Set.find(H[i]); cnt=0; nxt++; if(nxt!=Set.end()) { LL N1=*nxt;int n1=id[N1]; sor[++cnt].key=abs(N1-H[i]),sor[cnt].id=n1,sor[cnt].num=N1; nxt++; if(nxt!=Set.end()) { LL N2=*nxt;int n2=id[N2]; sor[++cnt].key=abs(N2-H[i]),sor[cnt].id=n2,sor[cnt].num=N2; } } if(it!=Set.begin()) { pre--;LL P1=*pre;int p1=id[P1]; sor[++cnt].key=abs(P1-H[i]),sor[cnt].id=p1,sor[cnt].num=P1; if(pre!=Set.begin()) { pre--;LL P2=*pre;int p2=id[P2]; sor[++cnt].key=abs(P2-H[i]),sor[cnt].id=p2,sor[cnt].num=P2; } } sort(sor+1,sor+cnt+1,cid); int j=sor[1].id; if(cnt>0) { tt[i]=j; dis[i][0][1]=(LL)sor[1].key; } j=sor[2].id; if(cnt>1) { fa[i][0]=j; dis[i][0][0]=(LL)sor[2].key; } Set.erase(H[i]); id[H[i]]=0; } for(int j=1;j<=18;j++) for(int i=1;i<n;i++) { if(j==1) { fa[i][j]=tt[fa[i][0]]; dis[i][j][0]=dis[i][0][0]; dis[i][j][1]=dis[fa[i][0]][0][1]; } else { fa[i][j]=fa[fa[i][j-1]][j-1]; if(fa[i][j]) { dis[i][j][0]=dis[i][j-1][0]+dis[fa[i][j-1]][j-1][0]; dis[i][j][1]=dis[i][j-1][1]+dis[fa[i][j-1]][j-1][1]; } } }}struct Ans{ LL da,db;};Ans calc(int i,LL x){ Ans r; LL d=0,da=0,db=0;int u=i; for(int j=18;j>=1;j--) { if(dis[u][j][1]||dis[u][j][0]) if(dis[u][j][1]+dis[u][j][0]+d<=x) { da+=dis[u][j][0]; db+=dis[u][j][1]; d=da+db; u=fa[u][j]; } } if(dis[u][0][0]+d<=x) da+=dis[u][0][0]; r.da=da;r.db=db; return r;}int main(){ init(); LL fz=inf,fm=0,x,da,db; int pos=0;cin>>x; for(int i=1;i<=n;i++) { Ans r=calc(i,x); da=r.da;db=r.db; if(da*fm<fz*db&&da!=0) {fz=da;fm=db;pos=i;} else if(da!=0&&da*fm==fz*db&&H[pos]<H[i]) {fz=da;fm=db;pos=i;} if(da==0&&fm==0&&H[pos]<H[i]) {fz=da;fm=db;pos=i;} } cout<<pos<<endl; int m;scanf("%d",&m); for(int i=1;i<=m;i++) { int s;scanf("%d",&s); LL x;read(x); Ans r=calc(s,x); printf("%lld %lld\n",r.da,r.db); } return 0;}
2 0
- noip2012 开车旅行 set+倍增
- NOIP2012 开车旅行:SET+倍增
- 【倍增】【set】[NOIP2012] codevs1199 开车旅行
- NOIP2012 T3开车旅行 set+倍增
- NOIP2012 开车旅行 (倍增)
- NOIP2012 开车旅行 【倍增】
- 【vijos1780】【NOIP2012】开车旅行 倍增
- NOIP2012 开车旅行 (倍增)
- noip2012 开车旅行 (倍增处理)
- NOIP2012 开车旅行 [Splay] [ST倍增]
- 【NOIP 2012】开车旅行 倍增+set
- 【NOIP2012】开车旅行
- NOIP2012 开车旅行
- NOIP2012 D1T3 开车旅行
- 【NOIP2012】Day1T3 开车旅行
- NOIP2012 开车旅行
- NOIP2012开车旅行
- NOIp2012开车旅行
- Redis 列表(List)
- Android系统篇之----Hook系统的AMS服务实现应用启动的拦截功能----一、Hook系统剪切板服务流程回顾在之前的一篇文章中已经介绍了 Android中的应用启动流程,这个流程一定要理
- javascript设计模式(四) 职责链模式 中介者模式
- Socket
- C++ CCF 火车购
- noip2012 开车旅行 set+倍增
- NOIP2009靶形数独
- action使用dao导致连接不释放
- iOS之开发SDK(.framework和.bundle)(包括支持ATS和ssl双向验证及瘦身)
- 让浏览器不再显示 https 页面中的 http 请求警报
- 亚马逊网站推荐的销售转化率----亚马逊推荐系统转化率很高是广为认可的,可是神话般的60%转化率,却源自片面取样,无可否认在某些情况下可以高达60%,但也仅限于某些特定条件的数据取样。但如果刻意选择某
- android最简单的视频下载
- (九)jmeter-参数化---学习笔记
- 如何识别高级的验证码