• 洛谷 P1314 聪明的质监员【二分+前缀和】


    真是zz,
    题目很显然是二分W,然后判断,我一开始是用线段树维护当前w[i]>W的个数和v(公式就是区间满足要求的个数*满足要求的v的和),然后T成70

    后来想到树状数组差分常数或许会小,于是改了一发,A了!

    但是这两个都是log方的,应该不会这么卡常数,于是我看了看update
    哦,直接做数组前缀和就行了,去掉了一个log

    所以不能想到一个复杂度差不多的算法就放弃思考……

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=200005;
    long long n,m,s,w[N],v[N],a[N],b[N],t[N],ts[N];
    long long read()
    {
    	long long r=0,f=1;
    	char p=getchar();
    	while(p>'9'||p<'0')
    	{
    		if(p=='-')
    			f=-1;
    		p=getchar();
    	}
    	while(p>='0'&&p<='9')
    	{
    		r=r*10+p-48;
    		p=getchar();
    	}
    	return r*f;
    }
    long long ok(long long mid)
    {
    	memset(t,0,sizeof(t));
    	memset(ts,0,sizeof(ts));
    	long long r=0;
    	for(int i=1;i<=n;i++)
    		if(w[i]>=mid)
    			t[i]=1,ts[i]=v[i];
    	for(int i=2;i<=n;i++)
    		t[i]+=t[i-1],ts[i]+=ts[i-1];
    	for(int i=1;i<=m;i++)
    		r+=(t[b[i]]-t[a[i]-1])*(ts[b[i]]-ts[a[i]-1]);
    	return r;
    }
    int main()
    {
    	n=read(),m=read(),s=read();
    	for(int i=1;i<=n;i++)
    		w[i]=read(),v[i]=read();
    	for(int i=1;i<=m;i++)
    		a[i]=read(),b[i]=read();
    	long long l=0,r=1e6,ansl=l,ansr=r;
    	while(l<=r)
    	{
    		long long mid=(l+r)>>1,nw=ok(mid);//cerr<<mid<<" "<<nw<<endl;
    		if(nw<=s)
    			r=mid-1,ansl=nw;
    		else
    			l=mid+1;
    	}
    	l=0,r=1e6;
    	while(l<=r)
    	{
    		long long mid=(l+r)>>1,nw=ok(mid);
    		if(nw>=s)
    			l=mid+1,ansr=nw;
    		else
    			r=mid-1;
    	}//cerr<<ansl<<" "<<ansr<<endl;
    	printf("%lld
    ",min(s-ansl,ansr-s));
    	return 0;
    }
    
  • 相关阅读:
    WPF开发进阶
    WPF开发进阶
    java 架构好文章
    Logback 输出 JPA SQL日志 到文件
    Linux Bash Shell j简单入门
    java内存空间简述
    PowerDesigner 16.5 反向PostgreSQL9.01 中 Unable to list the columns. SQLSTATE = 22003不良的类型值 short : t 解决方法
    Java代码自动部署
    Oracle优化技巧
    string类型与ASCII byte[]转换
  • 原文地址:https://www.cnblogs.com/lokiii/p/9780315.html
Copyright © 2020-2023  润新知