P1204 [USACO1.2]挤牛奶Milking Cows 线段树优化
P1204 [USACO1.2]挤牛奶Milking Cows
从暴力思想出发,建立一个bool数组用来标记哪些时间有挤牛奶,哪些时间空闲,然后从有挤牛奶的时间开始统计每一个段挤牛奶时间和空闲时间,并求最长挤牛奶时间和最长空闲时间,这样做时间复杂度为O(n*s),s为挤牛奶的时间长度,会TLE。如果优化呢?对于挤牛奶时间可以看成区间更新,然后统计每个时间点有多少人挤牛奶,可看成单点查询,故可以使用线段树进行优化时间复杂度O(nlogs)。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int t[maxn<<2];
int b[maxn];
void build(int rt,int l,int r)
{
if (l==r) return ;
int mid=(l+r)>>1;
build(2*rt,l,mid);
build(2*rt+1,mid+1,r);
}
void update(int rt,int l,int r,int ql,int qr,int k)
{
if (ql<=l&&r<=qr)
{
t[rt]=k;
}
else
{
int mid=(l+r)>>1;
if (ql<=mid) update(rt*2,l,mid,ql,qr,k);
if (qr>mid) update(rt*2+1,mid+1,r,ql,qr,k);
}
}
int getsum(int rt,int l,int r,int x)
{
if (l==r)
{
return t[rt];
}
else
{
int mid=(l+r)>>1;
if (x<=mid) return t[rt]+getsum(rt*2,l,mid,x);
else return t[rt]+getsum(2*rt+1,mid+1,r,x);
}
}
int main()
{
ios::sync_with_stdio(false);
int lmin=1e6,rmax=0;
int n;
cin>>n;
build(1,0,1e6);
for (int i=1;i<=n;i++)
{
int x,y;
cin>>x>>y;
lmin=min(lmin,x);rmax=max(rmax,y);
update(1,0,1e6,x,y-1,1);
}
for (int i=lmin;i<=rmax;i++)
{
b[i]=getsum(1,0,1e6,i);
}
int ans1=0,ans2=0,c1=0,c2=0;
for (int i=lmin;i<=rmax;i++)
{
if (b[i]==0)
{
ans1=max(ans1,c2);
c1++;
c2=0;
}
else
{
ans2=max(ans2,c1);
c2++;
c1=0;
}
}
cout<<ans1<<" "<<ans2<<endl;
return 0;
}
/*
3
300 1000
700 1200
1500 2100
*/
浙公网安备 33010602011771号