1917: E
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 108 Solved: 13
Submit Status Web Board
Description
晴天有非常严重的选择恐惧症,每次吃饭前他都在纠结到底吃什么。。今天又到了吃饭的时候了。
重光:我给你一个包含n个不同整数的序列a,如果它所有连续子序列的价值和是素数咱们就吃米,不然就吃面。
定义一个序列的价值为序列中所有元素的最小值。
晴天:这不是分分钟给你算出来。
嗯...十分钟过去了,晴天选择死亡。
这个任务就交给你啦。
算出所有连续子序列的价值和。
Input
第一行输入一个整数t,代表有t组测试数据。
每组数据第一行包含一个整数n,表示序列a的元素个数。
接下来一行包含n个整数,表示序列a。
0<=n<=50000,1<=ai<=50000。
Output
对于每组数据输出一个整数,表示序列a的所有连续子序列的价值和。
Sample Input
131 2 3
Sample Output
10
HINT
Source
思路:找出每个元素前后比他小,并且最靠近他的元素的位置,在他们之间,所有的子序列的价值都是该元素。
虽然想到要这么解,但是却没想到要怎么实现,肯定不能直接用for循环啊,这里用了,vector容器,以及二分(要会学以致用)
#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std;
struct node
{
int val,hao;
}t[51000];
bool cmp(node a,node b)
{
return a.val<b.val;
}
int main()
{
int T,n,i,j,k;
scanf("%d",&T);
while(T--)
{
vector<int>g;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&t[i].val);
t[i].hao=i;
}
sort(t+1,t+n+1,cmp);
g.push_back(0);
g.push_back(n+1);
long long ans=0;
for(i=1;i<=n;i++)
{
int k=upper_bound(g.begin(),g.end(),t[i].hao)-g.begin();
ans+=t[i].val*(t[i].hao-g[k-1])*(g[k]-t[i].hao);
g.insert(g.begin()+k,t[i].hao);
}
printf("%lld\n",ans);
}
return 0;
}