版权声明:All rights reserved. https://blog.csdn.net/qq_42814118/article/details/81365176
题
网上都有,自己搜去
解
暴力
65分暴力:用个优先队列,然后模拟,复杂度
代码见下:
#include <bits/stdc++.h>
using namespace std;
#define R register
int n,m,q,t,nowtime;
double u,v,p;
struct QY
{
int len,born;
QY() {len=0,born=0;}
int glen() {return len+(nowtime-born)*q;}
friend bool operator < (const QY &x,const QY &y)
{
return x.len+(nowtime-x.born)*q < y.len+(nowtime-y.born)*q;
}
};
priority_queue <QY,vector<QY>,less<QY> > Q;
int main()
{
scanf("%d %d %d %lf %lf %d",&n,&m,&q,&u,&v,&t);
p = u/v;
for (R int i=1;i<=n;++i)
{
R int tmp;
R QY tmp1;
scanf("%d",&tmp);
tmp1.len=tmp,tmp1.born=0;
Q.push(tmp1);
}
for (nowtime=0; nowtime<m;)
{
R QY tmp1=Q.top();
if(!((nowtime+1)%t)) printf("%d ",tmp1.glen());
Q.pop();
R int len1=floor((double)tmp1.glen()*p),len2=tmp1.glen()-len1;
++ nowtime;
R QY tmp2,tmp3;
tmp2.len=len1,tmp3.len=len2,tmp2.born=tmp3.born=nowtime;
Q.push(tmp2); Q.push(tmp3);
}
puts("");
R int cnt=0;
while(!Q.empty())
{
++ cnt;
R QY tmp1=Q.top();
if(!(cnt%t)) printf("%d ",tmp1.glen());
Q.pop();
}
return 0;
}
正解
这数据明显卡 log 。。。太恶劣了
初始蚯蚓们构成一个序列,
我们可以发现增长长度
是个常数,也就是初始蚯蚓们是同步增长的,
所以对初始序列sort后,它就是个单调不严格递减的队列,这个队列最长的蚯蚓就是队首
于是我们把被砍成一份的塞到一个队列里,另一份塞到另一个队列里。
我们可以证明这两个队列也是单调不严格递减的。
证明:
由于两个队列具对称性,我们证明其中一个就好了。
设有两个先后被砍的蚯蚓为
,其中
先于
被砍。
设中间过程过了
的时间。
那么放入这个队列里的蚯蚓按先后顺序长度分别为
(有没有下取整影响不大)
很明显,由于
,
,因此按照砍的先后顺序塞入队列中,这两个队列同样保持单调。
这样我们每次从三个队列中取个最大的抓出来砍掉,再塞入后两个队列,复杂度就变成线性的了。
代码如下,闲的无聊手写了个小队列模板:
#include <bits/stdc++.h>
using namespace std;
#define R register
#define Maxn 100005
#define Maxm 7000005
int n,m,q,t;
struct QY
{
int len,born;
QY(){len=0;born=0;}
inline int getlen(R int tim){return len+(tim-born)*q;}
};
inline bool cmp(R QY xx,R QY yy) {return xx.len>yy.len;}
struct Que
{
QY q[Maxm];
int head,tail;
Que(){memset(q,0,sizeof q);head=1,tail=0;}
inline QY front() {return q[head];}
inline void pop() {++head;}
inline void push(R QY val) {q[++tail]=val;}
inline bool empty() {return head > tail;}
}s[3];
double u,v,p;
int dmax(R int tim)
{
R int maxx=-1,maxi=-1;
for(R int i=0;i<3;++i)
{
if(s[i].empty()) continue;
R int tmp=s[i].front().getlen(tim);
if(tmp > maxx) maxx=tmp,maxi=i;
}
return maxi;
}
int main()
{
scanf("%d %d %d %lf %lf %d",&n,&m,&q,&u,&v,&t);
p = u/v;
for (R int i=1;i<=n;++i)
{
R QY tmp;
scanf("%d",&tmp.len);
s[0].push(tmp);
}
sort(s[0].q+1,s[0].q+n+1,cmp);
for (R int i=1;i<=m;++i)
{
R int Maxq=dmax(i-1),tmp=s[Maxq].front().getlen(i-1);
if(!(i%t)) printf("%d ",tmp);
s[Maxq].pop();
R int len1=floor(double(tmp*p)),len2=tmp-len1;
R QY tmp1;
tmp1.len=len1;tmp1.born=i;s[1].push(tmp1);
tmp1.len=len2;s[2].push(tmp1);
}
puts("");
for(R int i=1;i<=n+m;++i)
{
R int Maxq=dmax(m),tmp=s[Maxq].front().getlen(m);
if(!(i%t)) printf("%d ",tmp);
s[Maxq].pop();
}
return 0;
}