Cho dãy số A gồm N số nguyên 𝐴1, 𝐴2, … , 𝐴𝑁 (|A𝑖| ≤ 106; i = 1, 2, 3, ..., N) và số nguyên K. Hãy thực hiện các yêu cầu sau: - Tìm giá trị nhỏ nhất của giá trị các phần tử trong dãy số A và lớn hơn K. - Tìm cách chọn K phần tử liên tiếp nhau trong dãy số A sao cho tổng giá trị của chúng là lớn nhất. Dữ liệu vào từ tệp văn bản DAIDIEN.INP có cấu trúc: - Dòng thứ nhất ghi hai số nguyên dương N, K (1 ≤ 𝐾 ≤ 𝑁 ≤ 106). - Dòng thứ hai ghi N số nguyên 𝐴1, 𝐴2, … , 𝐴𝑁. - Các số trên mỗi dòng ghi cách nhau ít nhất một dấu cách. Dữ liệu ra ghi vào tệp văn bản DAIDIEN.OUT theo cấu trúc: - Dòng thứ nhất ghi một số là giá trị nhỏ nhất của giá trị các phần tử trong dãy số A và lớn hơn K. Nếu không tìm được giá trị của phần tử nào trong dãy số A thỏa mãn thì ghi số -1. - Dòng thứ hai ghi tổng giá trị lớn nhất của K phần tử liên tiếp nhau tìm được trong dãy số A. Ràng buộc: - Có 50% số test ứng với 50% số điểm có 𝑁 ≤ 103 , 𝐾 ≤ 2. - Có 30% số test ứng với 30% số điểm có 𝑁 ≤ 103 , 2 < 𝐾 ≤ 103. - Có 20% số test còn lại ứng với 20% số điểm có 103 < 𝑁,𝐾 ≤ 106. Ví dụ: DAIDIEN.INP DAIDIEN.OUT Giải thích INPUT 9 2 9 -1 9 -8 -2 -2 3 5 -8 OUTPUT 3 8
1 câu trả lời
#include <bits/stdc++.h>
using namespace std;
int f[1000005];
int n,m,k;
int d[1000001];
void nhap()
{
scanf("%d%d%d",&n,&m,&k);
}
void taomang()
{
f[1]=1;f[2]=1;
for (int i=3;i<=n;i++)
f[i]=(f[i-1]+f[i-2])%m;
}
void qs(int l,int r)
{
int i,j,x,t;
x=f[(l+r)/2];
i=l;j=r;
while (i<=j)
{
while (f[i]<x) i++;
while (f[j]>x) j--;
if (i<=j)
{
t=f[i];
f[i]=f[j];
f[j]=t;
i++;j--;
}
}
if (l<j) qs(l,j);
if (i<r) qs(i,r);
}
void taod()
{
int x=1,y=1,z;
for (int i=3;i<=n;i++)
{
z=(x+y)%m;
d[z]++;
y=x;
x=z;
}
}
void giai()
{
int res=0,i=-1;
while (res<k)
{
i++;
res+=d[i];
if (res>k)
{
printf("%d",i);
return;
}
}
printf("%d",i-1);
}
void xuli()
{
if (n<=1000000)
{
taomang();
qs(1,n);
printf("%d",f[k]);
}
else
{
taod();
giai();
}
}
int main()
{
nhap();
xuli();
}