【noip2016】【洛谷P2827】蚯蚓


這個題只知道可以用優先隊列去做,但是不知道正解想法,看到題解后恍然大悟,詳情請看代碼中間

#include<algorithm>
#include
<iostream>
#include
<cstring>
#include
<cstdio>
#include
<cmath>
using namespace std;
int n,m,q,u,v,t,q1[8000010],q2[8000010],q3[8000010],h1,h2,h3,t1,t2,t3;
bool cmp(int a,int b)
{
return a>b;
}
inline
int pop(int ti)
{
int top1=-1,top2=-1,top3=-1;
if(h1<=t1)
top1
=q1[h1]+(ti-1)*q;//對於初始的蚯蚓,開始時間是1
if(h2<=t2)
top2
=q2[h2]+(ti-h2-1)*q;//最早的被切開的蚯蚓開始增長於第二秒……所以多減個一
if(h3<=t3)
top3
=q3[h3]+(ti-h3-1)*q;
int flag=1,re=top1;
if(top2>re)//取個最大值
flag=2,re=top2;
if(top3>re)
flag
=3,re=top3;
if(flag==1)
h1
++;
if(flag==2)
h2
++;
if(flag==3)
h3
++;
return re;
}
inline
void push(int x)
{
long long qwq=(long long)x*u;
int a1=qwq/v,a2=x-a1;
if(a1<a2)
swap(a1,a2);
q2[
++t2]=a1,q3[++t3]=a2;//第二個隊列放較大的,第三個放較小的
}
/*因為早分解的一定開始較大,所以他們分解出來的蚯蚓也一定會較大
所以我們可以開三個隊列,分別用於維護未分解的蚯蚓,分解后較大的蚯蚓和較小的蚯蚓
那么每次所取的值,也一定在三個隊列之首中的一個
我們記錄頭指針尾指針,他們除了作為指針也可以用於判斷時間(很好理解,除了第一個隊列,其他都是按照加入隊列的時間來作為指針的)
這樣我們先都分解一遍,然后再從剩下兩個隊列里面彈就行了(越靠近隊首的越大)
*/
int main()
{
scanf(
"%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t);
for(int i=1;i<=n;i++)
scanf(
"%d",&q1[i]);
sort(q1
+1,q1+1+n,cmp);
h1
=1,t1=n,h2=h3=1;
for(int i=1;i<=m;i++)
{
int qaq=pop(i);
if(i-i/t*t==0)//判斷一下時間是不是t的倍數
cout<<qaq<<' ';
push(qaq);
}
cout
<<'\n';
for(int i=1;i<=m+n;i++)
{
int qaq=pop(m+1);
if(i-i/t*t==0)//判斷下大小是不是t的倍數
cout<<qaq<<' ';
}
cout
<<'\n';
}

 

关注微信公众号

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com