【34.54%】【codeforces 675E】Trains and Statistic
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard 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
Note
In the first sample it’s possible to get from any station to any other (with greater index) using only one ticket. The total number of pairs is 6, so the answer is also 6.
Consider the second sample:
ρ1, 2 = 1
ρ1, 3 = 2
ρ1, 4 = 3
ρ1, 5 = 3
ρ2, 3 = 1
ρ2, 4 = 2
ρ2, 5 = 2
ρ3, 4 = 1
ρ3, 5 = 1
ρ4, 5 = 1
Thus the answer equals 1 + 2 + 3 + 3 + 1 + 2 + 2 + 1 + 1 + 1 = 17.
【题解】
设dp[i]为i到i+1..n这些点的”总共”需要邮票的张数;
转移方程
dp[i] = dp[pos]+n-i-(a[i]-pos);
这里的pos,是(i+1..a[i])这个区间里面的a的值最大的下标;
表示的是从i开始往后转移的方式;
首先
从i->(i+1..a[i])都是只要一张票的。(这肯定是最优的)。所以不用从i到pos再转移到(pos+1..a[i]);
直接到pos+1..a[i]就可以了;
而a[i]之后的位置。则如果要到a[i]..a[pos]这段。则需要从i到pos再转移到。如下图。
上图中0->1、2、3、4、5、6这些都只要买一张票;
而dp[pos]包含了从pos->4、5的两张票;
如果再加上了dp[pos],则会重复;
因此要减去(a[i]-pos);
n-i+a[i]-pos
对应:
pos->a[i]后面的点;
然后从i连若干条边到pos;
因为有n-i+a[i]-pos个点。
所以总共要加n-i+a[i]-pos条边;
为什么选a最大的pos;
因为a[pos]是最大的。所以从pos可以走到更远的地方
如图,如果选择的是4。它最远能到8。则如果要到9就的再从8再买一张票到9;
而如果选择pos,则可以直接买一张票到9;这就节省了一张。
画图多理解下吧。
最后累加dp[1..n];
dp[n] = 0;
一开始dp[n-1]=1;
从n-2开始往前处理
获取某个区间内的最大值用ST算法就好(线段树is ok)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#define LL long long
using namespace std;
const int MAXN = 200000;
const int MAX = 17;
int n, a[MAXN],rmq[MAXN][MAX+3],pre[MAX+3];
int need[MAXN];
LL dp[MAXN],ans = 0;
void input(int &r)
{
r = 0;
char t = getchar();
while (!isdigit(t)) t = getchar();
int sign = 1;
if (t == '-')sign = -1;
while (!isdigit(t)) t = getchar();
while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
r = r*sign;
}
int main()
{
//freopen("F:\\rush.txt", "r", stdin);
scanf("%d", &n);
for (int i = 1; i <= n-1; i++)
scanf("%d", &a[i]),rmq[i][0] = i;
pre[0] = 1;
for (int i = 1; i <= MAX; i++)
pre[i] = pre[i - 1] * 2;
int now = 1;
need[1] = 0;
for (int i = 2; i <= n; i++)
if (i == pre[now])
need[i] = need[i - 1] + 1,now++;
else
need[i] = need[i - 1];
for (int l = 1;pre[l]<=n;l++)
for (int i = 1; i + pre[l]-1<= n; i++)
{
int left = rmq[i][l-1];
int right = rmq[i + pre[l - 1]][l-1];
if (a[left] > a[right])
rmq[i][l] = left;
else
rmq[i][l] = right;
}
dp[n-1] = 1;
ans = 1;
for (int i = n - 2; i >= 1; i--)
{
int xy = need[a[i] - i+1];
int left = rmq[i][xy], right = rmq[a[i] - pre[xy] + 1][xy];
int pos;
if (a[left] > a[right])
pos = left;
else
pos = right;
dp[i] = dp[pos] + n - i - (a[i] - pos);
ans += dp[i];
}
printf("%I64d\n", ans);
return 0;
}
【34.54%】【codeforces 675E】Trains and Statistic的更多相关文章
- codeforces 675E E. Trains and Statistic(线段树+dp)
题目链接: E. Trains and Statistic time limit per test 2 seconds memory limit per test 256 megabytes inpu ...
- 【 BowWow and the Timetable CodeForces - 1204A 】【思维】
题目链接 可以发现 十进制4 对应 二进制100 十进制16 对应 二进制10000 十进制64 对应 二进制1000000 可以发现每多两个零,4的次幂就增加1. 用string读入题目给定的二进制 ...
- 【34.57%】【codeforces 557D】Vitaly and Cycle
time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...
- 【24.34%】【codeforces 560D】Equivalent Strings
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【34.88%】【codeforces 569C】Primes or Palindromes?
time limit per test3 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【中途相遇法】【STL】BAPC2014 K Key to Knowledge (Codeforces GYM 100526)
题目链接: http://codeforces.com/gym/100526 http://acm.hunnu.edu.cn/online/?action=problem&type=show& ...
- 【codeforces 793D】Presents in Bankopolis
[题目链接]:http://codeforces.com/contest/793/problem/D [题意] 给你n个点, 这n个点 从左到右1..n依序排; 然后给你m条有向边; 然后让你从中选出 ...
- 【codeforces 799D】Field expansion
[题目链接]:http://codeforces.com/contest/799/problem/D [题意] 给你长方形的两条边h,w; 你每次可以从n个数字中选出一个数字x; 然后把h或w乘上x; ...
- 【22.73%】【codeforces 606D】Lazy Student
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
随机推荐
- Ubuntu 16.04下OLSR协议安装教程
OLSR是根据MANET的要求,在传统的LS(Link state)协议的基础上优化的. OLSR中的关键概念是多点转播(MPRs),MPRs是在广播洪泛的过程中挑选的转发广播的节点.传统的链路状态协 ...
- ActivityManagerService
先上类图: 基本类说明和运行框架图中蓝色表示AMS进程,黄色表示app进程.1. 全局调度者在android中,AMS是activity和进程的全局调度者,也就是说系统中载入和准备载入的activit ...
- Flutter SDK path为空导致工程打开后不显示iOS模拟器的问题
说明下问题场景,面向git编程时下载了个开源的Flutter项目 Mac系统下AndroidStudio打开工程后,发现顶部不展示iPhone模拟器 根据ide浅黄色提示提示,判断是FlutterSD ...
- Java练习 SDUT-3081_谁是最强女汉子
谁是最强的女汉子 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 众所周知,一年一度的女汉子大赛又来啦.由于最近女汉子比 ...
- OpenStack组件系列☞horizon搭建
第一步:部署horizon环境: 安装部署memcache 安装软件包 yum install memcached python-memcached 启动memcache并且设置开机自启动 syste ...
- 2018-8-10-win10-uwp-如何在DataTemplate绑定方法
title author date CreateTime categories win10 uwp 如何在DataTemplate绑定方法 lindexi 2018-08-10 19:16:50 +0 ...
- 微信小程序 mode 的几种模式
mode="aspectFill" mode 有效值: mode 有 13 种模式,其中 4 种是缩放模式,9 种是裁剪模式. 模式 值 说明缩放 scaleToFill 不保持纵 ...
- HZOJ 回家
这篇博客大部分在写我的错解……明明很简单的一道题,知道正解后10分钟AC,然而几个错解打的想死…… 错解1 WA40: 鬼知道这40分哪来的……这也是考试最后很无奈地交上去的代码,最后剩20分钟时发现 ...
- 【HAOI2015】树上染色
[HAOI2015]树上染色 这题思路好神仙啊,首先显然是树形dp,f[i][j]表示在以i为根的子树中选j个黑点对答案的贡献(并不是当前子树最大值),dp时只考虑i与儿子连边的贡献.此时(i,son ...
- H3C 主机单播IP包发送