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++; 
	}
}
posted @ 2020-10-05 17:20  xcxc82  阅读(166)  评论(0)    收藏  举报