P1204 [USACO1.2]擠牛奶Milking Cows 線段樹優化
阿新 • • 發佈:2022-03-07
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 */