NOIP2012Day1T3-开车旅行

NOIP2012Day1T3-开车旅行题解:首先我们可以分别建立小AAA和小BBB路程森林。其实森林也不用用边表去存储它,只要记录一下fa[i]fa[i]fa[i],即iii点的下一个点就可以了小AAA和小BBB旅行就等价于在这些森林里跑,很容易想到树上倍增。我们可以令f[i][j]f[i][j]f[i][j]为当前AAA开车在第iii个点经过2j2j2^j天后到达的点g1[i][j]g1[i][j]g1[i][j…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

NOIP2012Day1T3-开车旅行
题解:
首先我们可以分别建立小 A A 和小
B

B
路程森林。其实森林也不用用边表去存储它,只要记录一下 fa[i] f a [ i ] ,即 i i 点的下一个点就可以了

A

A
和小 B B 旅行就等价于在这些森林里跑,很容易想到树上倍增。
我们可以令
f[i][j]

f [ i ] [ j ]
为当前 A A 开车在第
i

i
个点经过 2j 2 j 天后到达的点
g1[i][j] g 1 [ i ] [ j ] 为当前 A A 开车在第
i

i
个点经过 2j 2 j 天后 A A 走的距离

g2[i][j]

g 2 [ i ] [ j ]
为当前 A A 开车在第
i

i
个点经过 2j 2 j 天后 B B 走的距离
为什么不需要记录当前
B

B
开车的状态?
j>=1 j >= 1 2j 2 j 后,还是 A A 开车,所以不需要记录
B

B
的状态
有了这三个数组,这道题就迎刃而解了。只要结尾状态和一些细节注意一下即可
Code C o d e :

#include<bits/stdc++.h>
#define N 100005
#define ll long long
#define inf 0x7fffffff
using namespace std;
struct node
{
    int d;ll v;
}p[N];
struct note
{
    int mx,mi;
}t[N*5];
bool cmp(node x,node y)
{
    return x.v<y.v||x.v==y.v&&x.d<y.d;
}
double sum,ans;
int n,m,tot,x,y,k,h[N],a[N],b[N],w[N],g[N][18];
ll f[N][18][2],ana,anb,v[N];
void change(int v,int l,int r,int x)
{
    if(l==r){t[v].mx=t[v].mi=l;return;}
    int m=(l+r)/2;
    if(x<=m)change(v*2,l,m,x);else 
        change(v*2+1,m+1,r,x);
    t[v].mx=max(t[v*2].mx,t[v*2+1].mx);
    t[v].mi=min(t[v*2].mi,t[v*2+1].mi);
}
int getmx(int v,int l,int r,int x,int y)
{
    if(x>y)return 0;
    if(l==x&&r==y)return t[v].mx;
    int m=(l+r)/2;
    if(y<=m)return getmx(v*2,l,m,x,y);else
        if(x>m)return getmx(v*2+1,m+1,r,x,y);else
            return max(getmx(v*2,l,m,x,m),getmx(v*2+1,m+1,r,m+1,y));
}
int getmi(int v,int l,int r,int x,int y)
{
    if(x>y)return n+1;
    if(l==x&&r==y)return t[v].mi;
    int m=(l+r)/2;
    if(y<=m)return getmi(v*2,l,m,x,y);else
        if(x>m)return getmi(v*2+1,m+1,r,x,y);else
            return min(getmi(v*2,l,m,x,m),getmi(v*2+1,m+1,r,m+1,y));
}
void solve(int x,int y)
{
    ana=anb=0;
    for(int j=17;j>=0;j--) 
        if(f[x][j][0]+f[x][j][1]<=y)
        {
            y-=f[x][j][0]+f[x][j][1];
            ana+=f[x][j][0];anb+=f[x][j][1];
            x=g[x][j];
        }
    if(f[x][0][0]<=y)ana+=f[x][0][0];
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%lld",&v[i]),p[i].v=v[i],p[i].d=i;
    sort(p+1,p+n+1,cmp);
    v[0]=inf;
    for(int i=1;i<=n;i++)
        h[p[i].d]=++tot,w[tot]=p[i].d;
    for(int i=1;i<=n*5;i++)t[i].mi=n+1;
    for(int i=n;i>=1;i--)
    {
        p[1].d=getmi(1,1,n,h[i]+1,n);p[2].d=getmx(1,1,n,1,h[i]-1);
        p[3].d=getmi(1,1,n,p[1].d+1,n);p[4].d=getmx(1,1,n,1,p[2].d-1);
        for(int j=1;j<=4;j++)p[j].v=abs(v[i]-v[w[p[j].d]]);    
        sort(p+1,p+5,cmp);
        if(p[1].d!=0&&p[1].d!=n+1)b[i]=w[p[1].d];
        if(p[2].d!=0&&p[2].d!=n+1)a[i]=w[p[2].d];
        change(1,1,n,h[i]);  
    }
    for(int i=1;i<=n;i++)
    {
        g[i][0]=b[a[i]];
        f[i][0][0]=abs(v[i]-v[a[i]]);
        f[i][0][1]=abs(v[a[i]]-v[b[a[i]]]);
    }
    for(int j=1;j<=17;j++)
        for(int i=1;i<=n;i++)
        {
            g[i][j]=g[g[i][j-1]][j-1];
            f[i][j][0]=f[i][j-1][0]+f[g[i][j-1]][j-1][0];
            f[i][j][1]=f[i][j-1][1]+f[g[i][j-1]][j-1][1];
        }
    scanf("%d",&x);ans=inf;
    for(int i=1;i<=n;i++)
    {
        solve(i,x);
        if(!anb)sum=inf;
            else sum=ana*1.0/anb;
        if(sum<ans||sum==ans&&v[i]>v[k])
            ans=sum,k=i;
    }
    printf("%d\n",k);
    for(scanf("%d",&m);m;m--)
    {
        scanf("%d%d",&x,&y);
        solve(x,y);
        printf("%lld %lld\n",ana,anb);  
    }
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/172077.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Android物联网应用程序开发(智慧城市)—— 火焰监控界面开发

    Android物联网应用程序开发(智慧城市)—— 火焰监控界面开发效果:布局代码:<?xmlversion=”1.0″encoding=”utf-8″?><RelativeLayoutxmlns:android=”http://schemas.android.com/apk/res/android”xmlns:app=”http://schemas.android.com/apk/res-auto”xmlns:tools=”http://schemas.android.com/tools”androi.

    2022年6月21日
    37
  • Onenote插件,云扩容

    Onenote插件,云扩容目录1.onenote2.插件3.云空间扩容4.onenote教程这些博主找了好久,现在一步到胃。特发布这篇文章,为后来的人指路。onenote各系列,公众号“软件管家”,有365,2016-2021系列,可正常同步。插件onetastic,直接官网免费onenoteclipper同onenotegem珍,有16版的,亲测可用于365版本。复制这段内容打开「百度网盘」APP即可获取链接:https://pan.baidu.com/s/1DtWmSRQ3cy1S6upA6DLU

    2025年10月12日
    10
  • GitHub Universe 2020 强势登陆,GitCode 直播已上线

    GitHub Universe 2020 强势登陆,GitCode 直播已上线什么是GitHubUniverse?GitHubUniverse是GitHub的年度选框产品和社区活动,聚集了构建全球最重要技术的GitHub产品专家,软件领导者和企业团队。GitHub的全球互联社区有机会聚在一起,分享最佳实践,互相学习,并了解GitHub的最新产品和功能。谁应该参加GitHubUniverse?开发人员:会议议题专为运行各种规模项目的开源贡献者和维护者以及希望了解最新软件工具,技术和最佳实践的开发人员而设计。通过深入研究Codespaces,Kubernetes部署

    2022年7月16日
    20
  • Java中的队列[通俗易懂]

    Java中的队列[通俗易懂]目录参考Deque从初学者的角度,认真地学习Java中队列的使用和设计。参考javadocDeque一个支持两端插入和删除的线性集合,此接口支持容量受限和不受限的双端队列(大多数实现容量不受限)。该接口定义了访问两端元素的方法,主要是插入、删除、检查元素方法。这些方法主要有两种形式,一种在操作失败时引发异常,一种在操作失败时返回特殊值(null或者false)。这里着重提一下插入操作,只有当队列容量受限时,插入操作才可能失败。12个方法如下该接口扩展了Queue接口。当双端队列

    2022年7月9日
    27
  • 【Java】一篇文章带你了解String、StringBuffer和StringBuilder的区别

    【Java】一篇文章带你了解String、StringBuffer和StringBuilder的区别String:字符串常量StringBuffer:字符串变量(多线程情况下使用,保护线程安全)synchronized:保护线程安全的StringBuilder:字符串变量(单线程情况下使用)String、StringBuffer、StringBuilder的主要区别:1.String类的内容不可以修改,而StringBuffer和StringBuilder的内容可以修改;2.StringBuffer和StringBuilder的大部分功能都是相似的;3.StringBu..

    2022年7月17日
    19
  • SPSS异方差检验的实现

    SPSS异方差检验的实现SPSS 异方差检验的实现此次介绍两种异方差检验的方法 残差图分析法和等级相关系数法残差图分析法当回归模型满足所有假定时 残差图上的 n 个点的散步应该是随机的 无任何规律 如果回归模型存在异方差性 残差图上的点散布会呈现一定的趋势 在 SPSS 中选择 转换 回归 线性 分别选入对应的自变量因变量 点击 保存 在残差栏中选择未标准化 确定 选择 图形 旧对话框 散点图 将未标准化的残差选入 X 轴 自变量选入 Y 轴点击 确定 得到残差图等级相关系数法计算残差步骤在 1 中已演示

    2025年6月23日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号