CF div2 E. Water Balance

给你n个数,你可以这样操作:使区间[l,r]的数变成 他们的平均数,求字典序最小的序列。

做法:从左往右逐个比较,比较完之后会形成一个区间,一开始是区间为1的数进行比较,到后来会

变成区间较大的进行比较;

举个例子:7 6 5 4 3 2 3

显而易见,递减序列肯定是要求平均值的,但是求出来之后,会得出一个值,这个值有可能大于或小于等于右边的数

这就需要再次进行比较,所以每次比较都是以区间的形式;

代码中区间为block

 1 #include<bits/stdc++.h>
 2 #define IOS ios::sync_with_stdio(false);cin.tie(0)
 3 #define ll long long
 4 //#define ll unsigned long long
 5 #define R register int
 6 #define inf 0x3f3f3f3f
 7 #define mod 1000000007
 8 #define eps 1e-6
 9 #define pi acos(-1)
10 #define mea (memset(a,0,sizeof(a)))
11 #define myit set<ll>::iterator
12 #define myits  multiset<ll>::iterator
13 #define v30 (1<<30)-1
14 #define all(x) (x).begin(),(x).end()
15 #define maxs *s.rbegin()
16 #define fi first
17 #define se second
18 using namespace std;
19 inline ll read(){
20    ll s=0,w=1;
21    char ch=getchar();
22    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
23    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
24    return s*w;
25 }
26 void put1(){ puts("YES") ;}
27 void put2(){ puts("NO") ;}
28 void put3(){ puts("-1"); }
29 ll gcd(ll a,ll b){ return b==0?a:gcd(b,a%b);}
30 using namespace std;
31 
32 const int manx=2e6+5;
33 
34 double water[manx]; //
35 double block[manx]; //区间块的长度
36 double ans[manx]; //答案
37 
38 int main()
39 {
40     ll n = read();
41     for ( int i=1; i<=n ;i++)
42         scanf("%lf",&water[i]);
43     ll l = 0;
44     for ( int i=1 ; i<=n ;i++){
45         ans[++l] = water[i];
46         block[l] = 1;
47         while ( l>1 && ans[l] < ans[l-1]){
48             ans[l-1]=( ans[l-1]* block[l-1] + ans[l] * block[l])
49             / ( block[l] + block[l-1]);
50             block[l-1] += block[l];
51             --l;
52         }
53     }
54     for ( int i=1 ; i<=l ;i++)
55         for ( int j=1 ; j<= block[i]; j++)
56             printf("%.9lf\n",ans[i] );
57     return 0;
58 }

猜你喜欢

转载自www.cnblogs.com/pangbi/p/12294617.html