1917: E
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 110 Solved: 15
Submit Status Web Board
Description
晴天有非常严重的选择恐惧症,每次吃饭前他都在纠结到底吃什么。。今天又到了吃饭的时候了。
重光:我给你一个包含n个不同整数的序列a,如果它所有连续子序列的价值和是素数咱们就吃米,不然就吃面。
定义一个序列的价值为序列中所有元素的最小值。
晴天:这不是分分钟给你算出来。
嗯...十分钟过去了,晴天选择死亡。
这个任务就交给你啦。
算出所有连续子序列的价值和。
Input
第一行输入一个整数t,代表有t组测试数据。
每组数据第一行包含一个整数n,表示序列a的元素个数。
接下来一行包含n个整数,表示序列a。
0<=n<=50000,1<=ai<=50000。
Output
对于每组数据输出一个整数,表示序列a的所有连续子序列的价值和。
Sample Input
1 3 1 2 3
Sample Output
10
#include <stdio.h> #include <string.h> #include<stdlib.h> #include <vector> #include <algorithm> using namespace std; #define LL long long struct node { int num,id;//num记录数字大小,id,记录数字位置 }no[50011]; bool cmp(node a,node b) { return a.num < b.num; //数字从小到大排序 } int main() { int t,n; scanf ("%d",&t); while (t--) { scanf ("%d",&n); for (int i = 1 ; i <= n ; i++) { scanf ("%d",&no[i].num); no[i].id = i; } sort(no+1,no+1+n,cmp); vector<int>v; v.push_back(0); v.push_back(n+1);//便于准确查找位置 LL ans = 0; int p; for (int i = 1 ; i <= n ; i++) { p = upper_bound(v.begin(),v.end(),no[i].id)-v.begin();//以其位置序号作为查找依据 ans+=no[i].num*(no[i].id-v[p-1])*(v[p]-no[i].id);//起点位于v[p-1]到no[i].id,终点位于v[p]到no[i].id的区间价值都为no[i].num。 v.insert(v.begin() + p,no[i].id);//将no[i].id加入容器,使用vector的好处是可以在任意位置添加数,并且不用考虑所引起的数组变化 } printf ("%lld\n",ans); } return 0; }