• codeforces 675E E. Trains and Statistic(线段树+dp)


    题目链接:

    E. Trains and Statistic

    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Vasya commutes by train every day. There are n train stations in the city, and at the i-th station it's possible to buy only tickets to stations from i + 1 to ai inclusive. No tickets are sold at the last station.

    Let ρi, j be the minimum number of tickets one needs to buy in order to get from stations i to station j. As Vasya is fond of different useless statistic he asks you to compute the sum of all values ρi, j among all pairs 1 ≤ i < j ≤ n.

     
    Input
     

    The first line of the input contains a single integer n (2 ≤ n ≤ 100 000) — the number of stations.

    The second line contains n - 1 integer ai (i + 1 ≤ ai ≤ n), the i-th of them means that at the i-th station one may buy tickets to each station from i + 1 to ai inclusive.

     
    Output
     

    Print the sum of ρi, j among all pairs of 1 ≤ i < j ≤ n.

     
    Examples
     
    input
    4
    4 4 4
    output
    6
    input
    5
    2 3 5 5
    output
    17



    题意:

    a[i]表示从第i个车站可以一张票到第[i+1,a[i]]这些车站;
    p[i][j]表示从第i个车站到第j个车站的最少的票数,现在要求∑dp[i][j](1<=i<=n,i<j<=n);


    思路:

    dp[i]=∑p[i][j](i<j<=n);
    转移方程为dp[i]=dp[temp]+(n-i)-(a[i]-temp);
    其中temp表示[i+1,a[i]]中a[temp]最大的位置;

    AC代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define Riep(n) for(int i=1;i<=n;i++)
    #define Riop(n) for(int i=0;i<n;i++)
    #define Rjep(n) for(int j=1;j<=n;j++)
    #define Rjop(n) for(int j=0;j<n;j++)
    #define mst(ss,b) memset(ss,b,sizeof(ss));
    typedef long long LL;
    const LL mod=1e9+7;
    const double PI=acos(-1.0);
    const int inf=0x3f3f3f3f;
    const int N=1e5+25;
    int n,a[N];
    LL dp[N];
    struct Tree
    {
        int l,r,ans;
    }tr[4*N];
    void pushup(int o)
    {
        if(a[tr[2*o].ans]>a[tr[2*o+1].ans])tr[o].ans=tr[2*o].ans;
        else tr[o].ans=tr[2*o+1].ans;
    }
    void build(int o,int L,int R)
    {
        tr[o].l=L;
        tr[o].r=R;
        if(L==R)
        {
            tr[o].ans=L;
            return ;
        }
        int mid=(L+R)>>1;
        build(2*o,L,mid);
        build(2*o+1,mid+1,R);
        pushup(o);
    }
    int query(int o,int L,int R)
    {
        if(L<=tr[o].l&&R>=tr[o].r)return tr[o].ans;
        int mid=(tr[o].l+tr[o].r)>>1;
        if(R<=mid)return query(2*o,L,R);
        else if(L>mid)return query(2*o+1,L,R);
        else
        {
            int fl=query(2*o,L,mid),fr=query(2*o+1,mid+1,R);
            if(a[fl]>a[fr])return fl;
            else return fr;
        }
    }
    int main()
    {
        scanf("%d",&n);
        Riep(n-1)scanf("%d",&a[i]);
        a[n]=n-1;
        build(1,1,n);
        LL ans=0;
        dp[n]=0;
        for(int i=n-1;i>0;i--)
        {
            int temp=query(1,i+1,a[i]);
            dp[i]=dp[temp]+(LL)(n-i-(a[i]-temp));
            ans+=dp[i];
        }
        cout<<ans<<"
    ";
    
        return 0;
    }
  • 相关阅读:
    页面中多个小图片元素合成一个大图片之后用CSS调用
    腾讯设计中心博客
    php 配置 curl , gd , openssl , mbstring
    Apache开启Rewrite环境
    防止入侵:My SQL各种攻击方法大全
    Css背景图合并工具功能增强
    php防CC攻击代码
    网站地址栏的图标代码
    PHP漏洞全解(一)PHP网页的安全性问题
    用PHP实现飞信api接口发飞信短信
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/5507077.html
Copyright © 2020-2023  润新知