【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 ...
随机推荐
- 只想着一直调用一直爽, 那API凭证泄漏风险如何破?
如今各家云厂商都通过给用户提供API调用的方式来实现一些自动化编排方面的需求.为了解决调用API过程中的通信加密和身份认证问题,大多数云厂商会使用同一套技术方案—基于非对称密钥算法的鉴权密钥对,这里的 ...
- docker在windows下的安装
Docker for Windows会默认包含两个引擎containers(linux和windows) 1. 下载Docker for Windows,https://docs.docker.com ...
- MaxCompute 费用暴涨之新增SQL分区裁剪失败
现象:因业务需求新增了SQL任务,这SQL扫描的表为分区表,且SQL条件里表只指定了一个分区,按指定的分区来看数据量并不大,但是SQL的费用非常高.费用比预想的结果相差几倍甚至10倍以上. 若只知道总 ...
- Implement strStr() 字符串匹配
Implement strStr(). Returns the index of the first occurrence of needle in haystack, or -1 if needle ...
- 域名拆分 tld
概念 URL Universal Resource Locator ,统一资源定位符. 用处:用来标识互联网资源的唯一地址. 本质:提供了互联网上任一资源地址的通用表示方法. protocol://h ...
- ELK2之ELK的语法学习
1.回顾 (1)es是什么? es是基于Apache Lucene的开源分布式(全文)搜索引擎,提供简单的RESTful API来隐藏Lucene的复杂性. es除了全文搜索引擎之外,还可以这样描述它 ...
- CDQ分治 三维偏序
这应该是一道CDQ分治的入门题目 我们知道,二维度的偏序问题直接通过,树状数组就可以实现了,但是三维如何实现呢? 我记得以前了解过一个小故事,应该就是分治的. 一个皇帝,想给部下分配任务,但是部下太多 ...
- TAE words
love handle pang carbohydrate podiatry splay out Cinderella liposuction mingle fly t ...
- ngRoute
ngRoute 模块中包含以下内容, 名称 所属 作用 ngView DIRECTIVE 提供不同路由模板插入的视图层 $routeProvider PROVIDER 提供路由配置 $route SE ...
- css样式书写规范
在工作当中css样式是非常重要的,但是咋样书写css样式更重要. 一.css书写规范 1.定位属性:position display float left top right bottom ...