Trains and Statistic [CodeForces - 675E]

本文解析了一道CodeForces上的题目E,介绍了如何利用线段树进行优化求解,并给出了具体的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://codeforces.com/contest/675/problem/E

题意

给出一个长度为n的数组nx,表示从站台i出发可以做一班车走到[i+1,nx[i]],令dis(i,j)表示i到j最少坐几班车,求 ni=1nj=i+1dis(i,j) ∑ i = 1 n ∑ j = i + 1 n d i s ( i , j )

分析

从后往前倒着推吧…然后用线段树优化一下。
然后还有个求和的过程。
…好像比想象的要麻烦。某段区间集体+1

不过还是很麻烦的。
要考虑到达某个点会不会造成影响之类的….?

先来考虑暴力的转移
dp[i]=min( dp[j]-(a[i]-(j+1)+1) +(n-(a[i]+1)+1) )+a[i]-(i+1)+1
(i+1<=j<=a[i])
然后化简一下就可以直接用线段树维护了。

结束。
一开始觉得很难想反而吓到自己了。其实只要抓住最暴力的dp就可以根据形态进行优化了。也算是一个小经验[?],当然很多时候通过性质优化才王道。

code

#include<bits/stdc++.h>
using namespace std;
void read(int &x){
    x=0; char c=getchar();
    for (;c<48;c=getchar());
    for (;c>47;c=getchar())x=(x<<1)+(x<<3)+(c^48);
}
#define ll long long 
#define M 100005
ll dp[M];
struct Tree{
    #define ls (p<<1)
    #define rs (p<<1|1)
    ll a[M<<2];
    void upd(int l,int r,int x,ll val,int p){
        if (l==r){
            a[p]=val;
            return;
        }
        int mid=(l+r)>>1;
        if (x<=mid)upd(l,mid,x,val,ls);
        else upd(mid+1,r,x,val,rs);
        a[p]=min(a[ls],a[rs]);
    }
    ll qu(int l,int r,int x,int y,int p){
        if (l==x&&r==y)return a[p];
        int mid=(l+r)>>1;
        if (y<=mid)return qu(l,mid,x,y,ls);
        if (x>mid)return qu(mid+1,r,x,y,rs);
        return min(qu(l,mid,x,mid,ls),qu(mid+1,r,mid+1,y,rs));
    }
}T;
int n,a[M];
int main(){
    ll res=0;
    read(n);
    for (int i=1;i<n;i++)read(a[i]);
    T.upd(1,n,n,2*n,1);
    for (int i=n-1;i;i--){
        dp[i]=T.qu(1,n,i+1,a[i],1);
        dp[i]=dp[i]-a[i]-i;
        res+=dp[i];
        T.upd(1,n,i,dp[i]+i+n,1);
    }
    printf("%lld\n",res);
    return 0;
}

总结

我居然把线段树打错了…某个max打成min了。傻掉了傻掉了,还调了很久…

关于常数

似乎可以通过把线段树换成倍增之类的方法来让常数变小。然而总的来说还是有点麻烦的… 我觉得46ms还可以啊[没上进心逃]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值