Problem E. Minima
Input file: minima.in
Output file: minima.out
Time limit: 2 seconds
Memory limit: 512 megabytes
You are given an array x[1 … n] and a number m. For all i from 1 to n−m+ 1 find the minimum among x[i], x[i + 1], … ,
x[i + m − 1] and return the sum of those minima.
Input
The first line of the input file contains three integer numbers: n, m and k (1 ≤ n ≤ 30 000 000, 1 ≤ m ≤ n,2 ≤ k ≤ min(n,1000)). The second line of the input file contains three integer numbers: a, b and c(−2^31 ≤ a, b, c ≤ 2^31 − 1). The third line of the input file contains k integer numbers: x[1],x[2], … , x[k](−2^31 ≤ x[i] ≤ 2^31 − 1).The rest of the array is calculated using the following formula: x[i] = f(a · x[i − 2] + b · x[i − 1] + c). Heref(y) returns such number −2^31 ≤ z ≤ 2^31 − 1 that y − z is divisible by 2^32.
Output
Print one integer number — the sum of minima of all subarrays of length m of the given array.
Example
minima.in
10 3 2
1 1 0
0 1
minima.out
33
minima.in
1000000 15 5
283471207 23947205 3
17625384 939393931 1838388 912740247 290470294
minima.out
-1879262596173354
题意
一段长为n的序列,给出前k项,后面n-k项可由题目中的函数推算,求所有长为m的区间的最小值之和
题解
维护一个双向队列即可,直接用优先队列会TLE。AC代码如下
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstdlib>
using namespace std;
struct node
{
int num;
int id;
bool operator<(const node &R)const
{
return num>R.num;
}
};
deque<node> Q;
int n,m,k;
int a,b,c;
int f1,f2;
int temp;
node shit;
long long ans=0;
int f(int x)
{
if(x<k-1)
{
scanf("%d",&x);
return x;
}
else if(x==k-1)
{
scanf("%d",&f1);
return f1;
}
else if(x==k)
{
scanf("%d",&f2);
return f2;
}
else
{
int t=a*f1+b*f2+c;
f1=f2;
f2=t;
return t;
}
}
int main()
{
freopen("minima.in","r",stdin);
freopen("minima.out","w",stdout);
scanf("%d%d%d",&n,&m,&k);
scanf("%d%d%d",&a,&b,&c);
int i;
for(i=1;i<m;i++)
{
temp=f(i);
while((!Q.empty())&&Q.back().num>temp)
Q.pop_back();
Q.push_back((node){temp,i});
}
for(;i<=n;i++)
{
temp=f(i);
while((!Q.empty())&&Q.back().num>temp)
Q.pop_back();
Q.push_back((node){temp,i});
while(Q.front().id<i-m+1)
Q.pop_front();
ans+=Q.front().num;
}
printf("%I64d\n",ans);
return 0;
}