您的位置:首页 > 其它

P1314 聪明的质监员

2017-07-01 14:56 169 查看

题目描述

小T 是一名质量监督员,最近负责检验一批矿产的质量。这批矿产共有 n 个矿石,从 1到n 逐一编号,每个矿石都有自己的重量 wi 以及价值vi 。检验矿产的流程是:

1 、给定m 个区间[Li,Ri];

2 、选出一个参数 W;

3 、对于一个区间[Li,Ri],计算矿石在这个区间上的检验值Yi:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
#define lli long long int
using namespace std;
const lli MAXN=200001;
void read(lli &n)
{
char c='+';lli x=0;bool flag=0;
while(c<'0'||c>'9')
{c=getchar();if(c=='-')flag=1;}
while(c>='0'&&c<='9')
{x=x*10+(c-48);c=getchar();}
flag==1?n=-x:n=x;
}
struct node
{
lli w,v;
}kuang[MAXN];
struct xw
{
lli l,r,id;
}q[MAXN];
lli n,m,s;
lli ans=0x7ffffff;
lli pos[MAXN];
lli base;
lli num,va;
lli comp(const xw &a,const xw &b)
{
if(pos[a.l]==pos[b.l])
return a.r<b.r;
else
return pos[a.l]<pos[b.l];
}
void add(lli p,lli need)
{
if(kuang[p].w>=need)
{
num++;
va+=kuang[p].v;
}
}
void dele(lli p,lli need)
{
if(kuang[p].w>=need)
{
num--;
va-=kuang[p].v;
}
}
lli pd(lli need)
{
lli ll=1,rr=0;
lli now=0;
num=0;va=0;
for(lli i=1;i<=m;i++)
{
for(;ll<q[i].l;ll++)
add(ll-1,need);
for(;ll>q[i].l;ll--)
dele(ll,need);
for(;rr>q[i].r;rr--)
dele(rr,need);
for(;rr<q[i].r;rr++)
add(rr+1,need);
now+=num*va;
}
if(now-s<ans&&now-s>0)
{
ans=now-s;
return 1;
}
else return 0;
}
int main()
{
read(n);read(m);read(s);
base=sqrt(n);
for(lli i=1;i<=n;i++)
pos[i]=(i-1)/base+1;
for(lli i=1;i<=n;i++)
{read(kuang[i].w);read(kuang[i].v);}
for(lli i=1;i<=m;i++)
{
read(q[i].l);read(q[i].r);
}
sort(q+1,q+m+1,comp);

lli ll=0,rr=5;
for(lli i=-500;i<=500;i++)
pd(i);
printf("%lld",ans);
return 0;
}


莫队
后来听大佬说直接暴力然后用前缀和优化一下就好

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
#define lli long long int
using namespace std;
const lli MAXN=300001;
void read(lli &n)
{
char c='+';lli x=0;bool flag=0;
while(c<'0'||c>'9')
{c=getchar();if(c=='-')flag=1;}
while(c>='0'&&c<='9')
{x=x*10+(c-48);c=getchar();}
flag==1?n=-x:n=x;
}
struct node
{
lli w,v;
}kuang[MAXN];
struct xw
{
lli l,r,id;
}q[MAXN];
lli n,m,s;
lli ans=0x7fffffff;
lli sum[MAXN],num[MAXN];
lli tot=0;
lli pd(lli W)
{
memset(num,0,sizeof(num));
memset(sum,0,sizeof(sum));
for (lli i=1;i<=n;i++)
{
sum[i]=sum[i-1];
num[i]=num[i-1];
if (kuang[i].w>=W)
{
sum[i]+=kuang[i].v;
num[i]++;
}
}
tot=0;
for (lli i=1;i<=m;i++)
tot+=(sum[q[i].r]-sum[q[i].l-1])*(num[q[i].r]-num[q[i].l-1]);
if (tot<=s) return true;
else return false;
}
int main()
{
//freopen("qc.in","r",stdin);
//freopen("qc.out","w",stdout);
read(n);read(m);read(s);
for(lli i=1;i<=n;i++)
{
read(kuang[i].w);read(kuang[i].v);
}
for(lli i=1;i<=m;i++)
{
read(q[i].l);read(q[i].r);
}

lli ll=0,rr=1000000;
while(ll<=rr)
{
lli mid=(ll+rr)>>1;
if(pd(mid))
{
rr=mid-1;
ans=mid;
}
else ll=mid+1;
}
ll=pd(ans);
lli a=tot;
rr=pd(ans-1);
lli b=tot;
printf("%lld",min(s-a,b-s));
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: