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 }