zoukankan      html  css  js  c++  java
  • Codeforces 675E Trains and Statistic

    Trains and Statisti

    我们考虑从一个点出发到达所有它后面所有位置所需要的次数和, 如果我们当前在x号点已经走了gg步,

    那么我们肯定将x能到达的那些没走过的点标为gg + 1, 然后找到x 到a[ x ]上的a值最大的点y, 然后 x 走到 y,  

    然后重复上述过程。 那么我们用一个cnt[ i ]数组表示 <= i的点起始经过 i 这个点的有多少个点, 然后进行计算, 

    这时候我们会碰到一个问题, 那些cnt[ i ]个到达 i 的其实位置有可能已经处理掉了一些 i 后面的终点, 我们在

    这些起始点转移到 i 之前把重复的减掉就好啦。

    感觉网上用dp写法更好理解一些。。

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ull unsigned long long
    
    using namespace std;
    
    const int N = 1e5 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-8;
    const double PI = acos(-1);
    
    int n, a[N];
    LL dis[N];
    LL cnt[N];
    
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    PII mx[N << 2];
    void build(int l, int r, int rt) {
        if(l == r) {
            mx[rt].fi = a[l];
            mx[rt].se = l;
            return;
        }
        int mid = l + r >> 1;
        build(lson); build(rson);
        mx[rt] = max(mx[rt << 1], mx[rt << 1 | 1]);
    }
    PII query(int L, int R, int l, int r, int rt) {
        if(l >= L && r <= R) return mx[rt];
        int mid = l + r >> 1;
        if(R <= mid) return query(L, R, lson);
        else if(L > mid) return query(L, R, rson);
        else return max(query(L, R, lson), query(L, R, rson));
    }
    
    int main() {
        scanf("%d", &n);
        for(int i = 1; i < n; i++) scanf("%d", &a[i]), cnt[i] = 0;
        build(1, n - 1, 1);
        LL ans = 0;
        for(int i = 1; i < n; i++) {
            cnt[i]++;
            PII tmp = query(i, a[i], 1, n - 1, 1);
            PII nxt = query(tmp.se, a[tmp.se], 1, n - 1, 1);
            ans += cnt[i] * (a[i] - i);
            ans += 2 * cnt[i] * (n - a[i]);
            ans -= cnt[i] * (tmp.fi - nxt.se);
            cnt[nxt.se] += cnt[i];
        }
        printf("%lld
    ", ans);
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    摘录:测试各阶段的意义
    EF Code First Migrations数据库迁移
    MVC5中Model层开发数据注解
    Easyui 中的placeholder属性
    在VS2012后的版本中做数据报表时,提示尚未指定报表“Report1”的报表定义
    MVC 中与链接相关的辅助方法(Html.ActionLink,Html.RouteLink , Url.Action , Url.Content ,Url.RouteUrl)
    Asp.net MVC中Html.Partial, RenderPartial, Action,RenderAction 区别和用法
    C# 常用对象的的修饰符
    C# 静态构造函数
    1、Singleton 单件(创建模式)
  • 原文地址:https://www.cnblogs.com/CJLHY/p/10443985.html
Copyright © 2011-2022 走看看