P2827 蚯蚓
大致题意
给\(n\)个数,\(m\)次操作,每次操作都将最大的一个数\(K\)分割为\(p×K\)和\(K-p×K\)两个数,每次操作后未被切割的数都会长长\(q\),现在要求:
1.第\(1t,2t,3t,...\)次操作时被切割的数的大小
2.排名为\(1t,2t,3t,...\)的数的大小
分析
算法一
直接开一个堆来模拟
可以获得\(90pts\)的超高分
复杂度约为\(O(mlogn)\)
\(code\)
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int X=0; bool flag=1; char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();}
while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}
if(flag) return X;
return ~(X-1);
}
priority_queue<int>que;
int n,m,q,u,v,t;
int val = 0;
int main(){
n = read(),m =read(),q =read(),u =read(),v =read(),t =read();
int qy;
for(int i=1;i<=n;i++){
qy = read();
que.push(qy);
}
double px = (double)u/v;
for(int i=1;i<=m;i++){
int now = que.top()+val;
val+=q;
que.pop();
int xx = (double)(px*now),yy = now - xx;
xx-=val,yy-=val;
que.push(xx),que.push(yy);
if(i%t==0) printf("%d ",now);
}
cout<<endl;
int T = 1;
while(!que.empty()){
int now = que.top()+val;
que.pop();
if(T%t==0) printf("%d ",now);
T++;
}
}
算法二
通过观察可以发现:
假设有两个数\(x\)和\(y\),且\(x≥y\),那么两个数被切割后分别为
\(p×x\)和\((1-p)×x\),\(p×y\)和\((1-p)×y\)
易得
\(p×x≥p×y\),\((1-p)×x≥(1-p)×y\)
说明被切割后的两个数具有单调性
可以开三个队列,一个存储经排序后的原数,另外两个分别存储被切割后的两个数
每次操作时取三个队首中最大的一个,并弹出即可
复杂度为\(O(m+nlogn)\)
\(code\)
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int X=0; bool flag=1; char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();}
while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}
if(flag) return X;
return ~(X-1);
}
queue<int>q1,q2,q3;
int n,m,q,u,v,t;
int a[100005];
int val = 0;
bool cmp(int x,int y){return x>y;}
void choise(int x){
if(x==1) q1.pop();
else if(x==2) q2.pop();
else q3.pop();
}
int main(){
n = read(),m =read(),q =read(),u =read(),v =read(),t =read();
int qy;
for(int i=1;i<=n;i++){
a[i] = read();
}
double px = (double)u/v;
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++){
q1.push(a[i]);
}
for(int i=1;i<=m;i++){
int que,now = -11451419;
if(!q1.empty()&&q1.front()+val>now) now = q1.front()+val,que = 1;
if(!q2.empty()&&q2.front()+val>now) now = q2.front()+val,que = 2;
if(!q3.empty()&&q3.front()+val>now) now = q3.front()+val,que = 3;
choise(que);
val+=q;
int xx = (double)(px*now),yy = now - xx;
xx-=val,yy-=val;
q2.push(xx),q3.push(yy);
if(i%t==0) printf("%d ",now);
}
int T = 1;
cout<<endl;
while(!(q1.empty()&&q2.empty()&&q3.empty())){
int que,now = -11451419;
if(!q1.empty()&&q1.front()+val>now) now = q1.front()+val,que = 1;
if(!q2.empty()&&q2.front()+val>now) now = q2.front()+val,que = 2;
if(!q3.empty()&&q3.front()+val>now) now = q3.front()+val,que = 3;
choise(que);
if(T%t==0) printf("%d ",now);
T++;
}
}

浙公网安备 33010602011771号