1. 程式人生 > >luogu2827 [NOIp2016]蚯蚓 (模擬)

luogu2827 [NOIp2016]蚯蚓 (模擬)

pop 隊列 ons ace print sin ron pair size

可以直觀地想到用優先隊列來做,但數據範圍是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 }

luogu2827 [NOIp2016]蚯蚓 (模擬)