CDQZ Challenge 19

来源:互联网 发布:office mac 更新补丁 编辑:程序博客网 时间:2024/04/29 17:33

说在前面:“CDQZ”系列题目数据绝对良心(良苦用心233),提交网址如有需要请私信本蒟蒻。
1019:Challenge 19
查看 提交 统计 提问
总时间限制: 70000ms 单个测试点时间限制: 5000ms 内存限制: 126000kB
描述
给你一个长为n序列a,找a中长度为k的子序列b,使得b的字典序尽可能大。
1<=ai<=1000000000
n<=15000000
k<=1000000

输入
第一行x,y,z,用于生成a序列:a[1]=x,a[i]=a[i-1]*y%z+1
第二行n,k
输出
k行k个数,表示b序列
样例输入
1 0 1
3 3
样例输出
1
1
1
来源
mhy12345

题解:用单调队列维护答案,每次选一段可以选的数里的最大值。单调栈也能过,但是栈必须要莫名其妙地开longlong。。。
单调队列:

/*    a[1]=x,a[i]=a[i-1]*y%z+1;*/#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef long long ll;const int MAXN=15000002;int a[MAXN];int n,k,x,y,z;int q[MAXN],h=1,t=0;inline int read() {    int x=0,f=1;char c=getchar();    while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}    while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();    return x*f;}int main() {//  freopen("Challenge 19.in","r",stdin);//  freopen("C19.in","r",stdin);    a[1]=x=read(),y=read(),z=read();    n=read(),k=read();    int j=n-k+1;    for (register int i=1;i<=j;++i) {        a[i]=i^1?(ll)a[i-1]*y%z+1:a[i];         while (h<=t&&a[q[t]]<a[i]) --t;        q[++t]=i;    }    for (register int i=1;i<=k;++i) {        a[i+j]=(ll)a[i+j-1]*y%z+1;        printf("%d\n",a[q[h++]]);        while (h<=t&&a[q[t]]<a[i+j]) --t;        q[++t]=i+j;    }    return 0;}

单调栈:

/*    a[1]=x,a[i]=a[i-1]*y%z+1;*/#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef long long ll;const int MAXN=15000002;ll a[MAXN];int n,k,x,y,z;ll q[MAXN],top=0;inline int read() {    int x=0,f=1;char c=getchar();    while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}    while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();    return x*f;}int main() {//  freopen("Challenge 19.in","r",stdin);//  freopen("C19.in","r",stdin);    a[1]=x=read(),y=read(),z=read();    n=read(),k=read();    q[++top]=a[1];    for (register int i=2;i<=n;++i) {        a[i]=a[i-1]*y%z+1;        while (a[i]>q[top]&&top>0&&top+n-i>=k) --top;        q[++top]=a[i];    }    for (int i=1;i<=k;++i) printf("%lld\n",q[i]);    return 0;}
原创粉丝点击