【niop2016】【luogu2827】蚯蚓 [队列 单调性]
和合并果子很像 合并果子是每次取最小的出来合并
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 id:gww 3 language:C-- 4 5 */ 6 #include<bits/stdc++.h> 7 using namespace std; 8 const int N=100000+10; 9 int n,m,q,u,v,t,lj=0; 10 double p; 11 priority_queue<int> l;//优先队列 从大到小 12 inline int rd() 13 { 14 int x=0,w=0;char ch=0; 15 while(!isdigit(ch)) w|=ch=='-',ch=getchar(); 16 while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); 17 return w?-x:x; 18 } 19 20 int xqz(double x) 21 { 22 double a=x*p; 23 int ans=(int)a/1; 24 return ans; 25 } 26 27 int main() 28 { 29 n=rd(),m=rd(),q=rd(),u=rd(),v=rd(),t=rd();p=(double)u/v; 30 for(int i=1;i<=n;i++) {int x=rd();l.push(x);} 31 for(int i=1;i<=m;i++) 32 { 33 int top=l.top()+lj,x1,x2;//被切的蚯蚓的长度 34 l.pop();lj+=q;//累加 35 x1=xqz((double)top),x2=top-x1; 36 l.push(x1-lj),l.push(x2-lj); 37 if(i%t==0) printf("%d ",top); 38 } 39 printf("\n"); 40 for(int i=1;!l.empty();i++) 41 { 42 if(i%t==0) printf("%d ",l.top()+lj); 43 l.pop(); 44 } 45 return 0; 46 }
用三个数组来存 q1表示蚯蚓原长 l表示被切成x*p r表示x-x*p 所以q1只取出不放
然后每次取最长的出来切
1 /* 2 id:gww 3 language:C-- 4 5 */ 6 #include<bits/stdc++.h> 7 using namespace std; 8 const int N=100000+10; 9 const int maxn=1e5+10; 10 const int maxm=1e7+10; 11 int n,m,q,u,v,t;double p; 12 int t1,h2,t2,h3,t3,h4; 13 int q1[maxn],l[maxm],r[maxm],q4[maxn+maxm]; 14 bool cmp(int a,int b) {return a>b;} 15 inline int rd() 16 { 17 int x=0,w=0;char ch=0; 18 while(!isdigit(ch)) w|=ch=='-',ch=getchar(); 19 while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); 20 return w?-x:x; 21 } 22 23 int get(int x)//取当前最长 24 { 25 int a=q1[t1]+q*x,b=l[t2]+q*(x-t2-1),c=r[t3]+q*(x-t3-1); 26 if(n>t1&&a>=b&&a>=c) {t1++;return a;} 27 else if(h2>t2&&b>=c) {t2++;return b;} 28 else if(h3>t3) {t3++;return c;} 29 else return -1; 30 } 31 32 int xqz(double x)//向下取整 33 { 34 double a=x*p; 35 int ans=(int)a/1; 36 return ans; 37 } 38 39 int main() 40 { 41 n=rd(),m=rd(),q=rd(),u=rd(),v=rd(),t=rd();p=(double)u/v; 42 for(int i=0;i<n;i++) q1[i]=rd(); 43 sort(q1,q1+n,cmp); 44 for(int i=0;i<m;i++) 45 { 46 int a,b,c; 47 a=get(i); 48 if((i+1)%t==0) printf("%d ",a);//切他! 49 b=xqz((double)a),c=a-b; 50 l[h2++]=b,r[h3++]=c; 51 } 52 putchar('\n'); 53 while(q4[h4]=get(m),q4[h4]!=-1) h4++;//骚操作 54 for(int i=t-1;i<h4;i+=t) printf("%d ",q4[i]); 55 putchar('\n'); 56 return 0; 57 }