luogu2827 [NOIp2016]蚯蚓 (模拟)

可以直观地想到用优先队列来做,但数据范围是O(n)的

然后我们发现,因为我们每次挑出来的蚯蚓是单调的,所以把每个切成两段后,那两段也是对应单调的

也就是说,算上最一开始的蚯蚓,我们一共维护三个队列,三个分别单调,每次取出来最大的那个队头就行了

 1 #include<bits/stdc++.h>
 2 #define pa pair<int,int>
 3 #define CLR(a,x) memset(a,x,sizeof(a))
 4 using namespace std;
 5 typedef long long ll;
 6 const int maxn=1e5+10,maxm=7e6+10;
 7 const ll inf=1e15;
 8 
 9 inline ll rd(){
10     ll x=0;char c=getchar();int neg=1;
11     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
12     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
13     return x*neg;
14 }
15 
16 int T;
17 int num[maxn];
18 ll N,M,q;
19 double p;
20 queue<ll> q1,q2,q3;
21 
22 int main(){
23     //freopen(".in","r",stdin);
24     int i,j,k;
25     N=rd(),M=rd();q=rd();
26     p=(double)rd()/rd();T=rd();
27     for(i=1;i<=N;i++) num[i]=rd();
28     sort(num+1,num+N+1);
29     for(i=N;i;i--) q1.push(num[i]);
30     for(i=1;i<=M;i++){
31         ll a=(q1.empty()?-inf:q1.front()),b=(q2.empty()?-inf:q2.front()),c=(q3.empty()?-inf:q3.front());
32         ll mm=max(a,max(b,c));
33         
34         if(a==mm) q1.pop();
35         else if(b==mm) q2.pop();
36         else if(c==mm) q3.pop();
37         mm+=q*(i-1);
38         ll x=(ll)(mm*p),y=mm-x;
39         q2.push(x-q*i),q3.push(y-q*i);
40         if(i%T==0) printf("%lld ",mm);
41     }printf("\n");
42     
43     for(i=1;(!q1.empty())||(!q2.empty())||(!q3.empty());i++){
44         ll a=(q1.empty()?-inf:q1.front()),b=(q2.empty()?-inf:q2.front()),c=(q3.empty()?-inf:q3.front());
45         ll mm=max(a,max(b,c));
46         // printf("%lld %lld %lld\n",a,b,c);
47         if(mm==-inf) break;
48         if(q1.front()==mm) q1.pop();
49         else if(q2.front()==mm) q2.pop();
50         else if(q3.front()==mm) q3.pop();
51         mm+=q*M;
52         if(i%T==0) printf("%lld ",mm);
53     }
54     
55     return 0;
56 }

猜你喜欢

转载自www.cnblogs.com/Ressed/p/9696020.html