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;	
}
posted @ 2018-08-14 21:49  Hyscere  阅读(134)  评论(0编辑  收藏  举报