2 条题解
-
0
思路
有以下结论:$\forall x_1\le x_2 \in \mathbb{Z},\lfloor px_1 \rfloor \le \lfloor px_2 \rfloor,x_1 - \lfloor px_1 \rfloor \le x_2 - \lfloor px_2 \rfloor$。
第一个式子很显然,因为 和 两个函数都是单调不降的。
下面来证明第二个式子。令函数 $y_x=x - \lfloor px \rfloor = \lceil x - px \rceil = \lceil (1 - p)x \rceil$。容易发现 和 两个函数也都是单调不降的,所以原函数 单调不降。
有了这个结论,我们就知道神刀手先切的蚯蚓形成的前一半,一定比后切的蚯蚓形成的前一半要长;先切的蚯蚓形成的后一半,一定比后切的蚯蚓形成的后一半要长。
所以可以维护三个队列,分别存初始蚯蚓、切出的前半条蚯蚓、切出的后半条蚯蚓。因为入队的顺序和入队的数字大小是负相关,所以三个队列都是单调的。对于增加量 ,只有两条蚯蚓没长就相当于这两条蚯蚓变短了 。可以维护一个增长量 表示所有蚯蚓变长的长度,每次切蚯蚓的时候都把切出的蚯蚓长度减 。
由于每次切的时候长度都要减 ,所以这个变长不影响队列的单调性。时间复杂度为 。
代码
#include<bits/stdc++.h> using namespace std; const int inf=1e9; int n,m,ad,u,v,t; int add; int a[1000003]; queue<int>q[3]; int get(){ int mxi=-1; for(int i=0;i<3;i++) if(!q[i].empty()&&(mxi==-1||q[mxi].front()<q[i].front()))mxi=i; int t=q[mxi].front(); q[mxi].pop(); return t; } int main(){ ios::sync_with_stdio(0); cin.tie(0);cout.tie(0); cin>>n>>m>>ad>>u>>v>>t; for(int i=1;i<=n;i++)cin>>a[i]; sort(a+1,a+1+n,greater<int>()); for(int i=1;i<=n;i++)q[0].push(a[i]); for(int i=1;i<=m;i++){ int x=get()+add,y; if(i%t==0)cout<<x<<' '; y=(long double)x*u/v; x-=y; add+=ad; y-=add; x-=add; q[1].push(x); q[2].push(y); } cout<<'\n'; for(int i=1;i<=n+m;i++){ int x=get(); if(i%t==0)cout<<x+add<<' '; } return 0; } -
0
用堆模拟的85分代码:
#include<bits/stdc++.h>//用堆模拟的85分代码 using namespace std; priority_queue<int>Q; int n,m,q,u,v,t; int main() { scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t); double p=(double)u/v; for(int i=1;i<=n;i++) { int a;scanf("%d",&a); Q.push(a); } for(int i=1;i<=m;i++) { if(i%t==0)printf("%d ",Q.top()+(i-1)*q); int x=Q.top()+(i-1)*q;Q.pop(); Q.push(floor(p*x)-i*q); Q.push(x-floor(p*x)-i*q); } printf("\n"); for(int i=1;i<=n+m;i++) { int x=Q.top();Q.pop(); if(i%t==0)printf("%d ",x+m*q); } printf("\n"); return 0; }3个队列100分代码:
#include<bits/stdc++.h> using namespace std; const int N=8e6; queue<int>q1,q2,q3; int n,m,q,u,v,t,delta; int a[N]; int getmax() { int a=q1.empty()?-2e9:q1.front(); int b=q2.empty()?-2e9:q2.front(); int c=q3.empty()?-2e9:q3.front(); int x=max(a,max(b,c)); if(x==a)q1.pop(); else if(x==b)q2.pop(); else if(x==c)q3.pop(); return x; } int main() { scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t); double p=(double)u/v; for(int i=1;i<=n;i++)scanf("%d",&a[i]); sort(a+1,a+n+1); for(int i=n;i>=1;i--)q1.push(a[i]); for(int i=1;i<=m;i++) { int x=getmax()+(i-1)*q; if(i%t==0)printf("%d ",x); q2.push(int(p*x)-i*q); q3.push(x-int(p*x)-i*q); } printf("\n"); for(int i=1;i<=n+m;i++) { int x=getmax()+m*q; if(i%t==0)printf("%d ",x); } printf("\n"); return 0; }
- 1
信息
- ID
- 6386
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 10
- 标签
- 递交数
- 7
- 已通过
- 4
- 上传者