您的位置:首页 > 其它

CSU1654: 收集金币

2015-05-31 18:25 225 查看


Description

有一条路上有一排的金币,如果把这条路看做一个数轴,那么在1~n的位置上各有一个金币,共n个,每个金币有一个不同的编号1~n(不一定按顺序).在0位置上有一个人,他有很多神奇的小车,他可以在0位置释放神奇的小车,每个小车一旦被释放就会沿着数轴正方向每个单位时间走一个单位距离.如果一个小车所在的位置有金币且这个金币的编号是剩余金币中编号最小的,而且如果收集了这个金币能保证这个小车收集到的金币编号是连续的,那么这个小车就会收集这个金币.神奇小车一旦走到n+1的位置就能把这个车上的金币转化为价值,如果这个车上有x个金币,就能转化出x*x单位的价值.在路上可能同时存在多个小车.</br>如果A小车和B小车都在路上,且A车位置有编号m的金币,B车位置有编号m+1的金币,m是剩余金币中最小的编号,这样A车可以收集m号金币,B车也可以收集m+1号金币.


Input

多个样例,每个样例占两行.第一行一个整数n(1 <= n <= 100000),之后一行n个整数,为1~n的一个排列.


Output

每行输出一个样例的结果,包括两个整数v和t,用空格隔开.

v表示那个人能转化出的最大价值.

t表示转化v价值要花的最少的时间.


Sample Input

5
3 4 1 2 5


Sample Output

13 9


HINT

第一个样例:在0时间释放第一个小车,3时间释放第二个小车,第二个小车在9时间到达6位置结束.第一个小车收集了1,2号金币,转化4个价值,第二个小车转化了9个价值.


Source



#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <math.h>
#include <bitset>
#include <algorithm>
#include <climits>
using namespace std;
 
#define LS 2*i
#define RS 2*i+1
#define UP(i,x,y) for(i=x;i<=y;i++)
#define DOWN(i,x,y) for(i=x;i>=y;i--)
#define MEM(a,x) memset(a,x,sizeof(a))
#define W(a) while(a)
#define gcd(a,b) __gcd(a,b)
#define LL long long
#define N 20005
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define EXP 1e-8
 
int n,a[100005],hsh[100005];
int v,t,s,x;
 
int main()
{
    int i,j,k;
    W(~scanf("%d",&n))
    {
        UP(i,1,n)
        {
            scanf("%d",&a[i]);
            hsh[a[i]] = i;
        }
        s = 1;
        v = t = 0;
        W(s<=n)
        {
            int cnt = 1;
            W(hsh[s+1]>hsh[s])
            {
                s++;
                cnt++;
            }
            v+=cnt*cnt;
            t+=hsh[s];
            s++;
        }
        printf("%d %d\n",v,t);
    }
 
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: