2018-8-14队测
这题考场上居然没想出来。。。然后被吊锤了。。
考场上随便写了个30分暴力
正解:
先累计前缀和\(sum[i]\)
然后对于区间\([i,j]\)
\[\frac{sum[j]-sum[i-1]}{j-i+1}\geq L
\]
令\(sum[i]\)同时减去\(L\)
\[sum[j]-sum[i-1]\geq 0
\]
\[sum[j]\geq sum[i-1]
\]
然后求逆序对,即可得到平均数大于\(L\)的
小于\(R\)的同理
update: 代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define read(x) scanf("%lld",&x)
#define write(x) printf("%lld\n",x)
#define lowbit(x) (x&-x)
#define maxn 2000050
int n,l,r,sum[maxn],x,a[maxn],b[maxn],c[maxn],ans;
struct binary_index_tree{
int tree[maxn];
void change(int x,int v){for(int i=x;i<=n;i+=lowbit(i)) tree[i]+=v;}
int query(int x,int ans=0){for(int i=x;i;i-=lowbit(i)) ans+=tree[i];return ans;}
}T1,T2;
signed main(){
read(n),read(l),read(r);
for(int i=1;i<=n;i++) read(x),a[i]=x-l,b[i]=x-r;
for(int i=1;i<=n;i++){
sum[i]=sum[i-1]+a[i],c[i]=sum[i];
if(c[i]<0) ans--;
}
sort(c+1,c+n+1);int m=unique(c+1,c+n+1)-c;
for(int i=1;i<=n;i++) sum[i]=lower_bound(c+1,c+m+1,sum[i])-c;
for(int i=n;i;i--) ans-=T1.query(sum[i]),T1.change(sum[i]+1,1);
memset(sum,0,sizeof sum);
for(int i=1;i<=n;i++){
sum[i]=sum[i-1]+b[i],c[i]=sum[i];
if(c[i]<=0) ans++;
}
sort(c+1,c+n+1);m=unique(c+1,c+n+1)-c;
for(int i=1;i<=n;i++) sum[i]=lower_bound(c+1,c+m+1,sum[i])-c;
for(int i=n;i;i--) ans+=T2.query(sum[i]),T2.change(sum[i],1);
int x=n*(n+1)/2;int tmp=__gcd(ans,x);
ans/=tmp,x/=tmp;
if(ans==x) write(1ll);
else if(ans==0) write(0ll);
else printf("%lld/%lld\n",ans,x);
return 0;
}
考场上dfs20分。。正解挖坑先。。
这题考场上居然想出了正解。。100pts
这题第一眼贪心,然后无果。。于是想dp
记\(f[i]\)为前\(i\)个星球的收入,然后考虑dp,发现这个能力值是有后效性的,无法dp,但是考虑到能力值对前面的不能造成影响,可以考虑逆向dp
然后就很简单了,记\(f[i]\)为\(i-n\)的收入,dp就一句话,看代码吧。。
#include<bits/stdc++.h>
using namespace std;
#define read(x) scanf("%d",&x)
#define write(x) printf("%.2lf\n",x)
#define maxn 200050
int v[maxn],op[maxn],n,kk,cc,w;
#define lf double
lf f[maxn],k,c;
int main(){
//freopen("exploit.in","r",stdin);
//freopen("exploit.out","w",stdout);
read(n),read(kk),read(cc),read(w);
k=1-0.01*kk,c=1+0.01*cc;
for(int i=1;i<=n;i++) read(op[i]),read(v[i]);
for(int i=n;i;i--) f[i]=max(f[i+1],op[i]==1?f[i+1]*k+v[i]:f[i+1]*c-v[i]);
write(f[1]*(lf)w);
return 0;
}