codeforces 1300E Water Balance

题目地址

思维

#include
#define pk push_back 
using namespace std;
typedef long long ll;
double dp[1000010],sum[1000010];
int main()
{
	int n,x;
	cin>>n;
	for(int i=1;i<=n;i++)
	cin>>x,dp[i]=x,sum[i]=sum[i-1]+dp[i];//前缀和 便于计算区间和
	for(int i=2;i<=n;i++)
	{
	    double cnt=dp[i];
		for(int j=i-1;j>=1;j--) //找到一个 低点
		{
			if(dp[j]>cnt)
			{
				cnt=(sum[i]-sum[j-1])/(i-j+1); 新区间平均值
				if(j==1)
				for(int k=j;k<=i;k++)
				dp[k]=cnt;  //区间更新
			}
			else
			{
				for(int k=j+1;k<=i;k++)
				dp[k]=cnt;  // 区间更新
				break;
			}
		}
	}
	for(int i=1;i<=n;i++)
	printf("%.9lf\n",dp[i]);
	return 0;
}

上面的代码妥妥TLE 所以我可以可以优化 区间更新和查找低点的过程

如下

#include
#define pk push_back 
using namespace std;
typedef long long ll;
double sum[1000010];
int x[1000010];
struct node
{
	int l,r;  // 区间[l,r]  
	double w;  //区间平均值
};
vector<node> a; // 任意一个线性结构
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	cin>>x[i],sum[i]=sum[i-1]+(double)x[i];
	a.pk((node){1,1,(double)x[1]});
	for(int i=2;i<=n;i++)
	{
		double cnt=(double)x[i];
		int l=i;
		for(int j=a.size()-1;j>=0;j--)
		{
			if(a[j].w>=cnt)
			{
				l=a[j].l;
				cnt=(sum[i]-sum[l-1])/(i-l+1);
				a.pop_back(); // 当前节点删去
				if(j==0)
				{
					a.pk((node){1,i,cnt});   // 新区间更新 变成了更新一个节点
					break;
				}
			}
			else
			{
				a.pk((node){l,i,cnt});
				break;
			}
		}
	}
	for(int i=0;i<a.size();i++)
	{
		for(int j=a[i].l;j<=a[i].r;j++)
		printf("%.9lf\n",a[i].w); 输出区间
	}
	a.clear();
	return 0;
}

你可能感兴趣的:(数据结构,acm,c++)