UVA 11983 Weird Advertisement (线段树扫描线)
2018-02-15 12:46
323 查看
题意:
现在在坐标系上,画正方形,问重叠k次及以上的区域里面有几个点(都在第一象限)思路:
扫描线比较有意思的一个题目首先,要把计算点个数变成计算面积,我们把一个点看成一个格子,因为都在第一象限,那么只要把每个长方形右上角的坐标各加一即可,这样计算出的面积就是答案了
现在的问题就成了如何计算k次及以上的面积了,首先我们不可能不断地pushdow来更新区域面积,肯定会T。我们发现题目中k最大只有10,然后我们就能想到,我们计算被覆盖了某个次数的面积,是可以由lazy(记录的是该区间覆盖了几次)和其他次数的面积推导过来的(比如我左儿子覆盖了2次,我的lazy为2,那么我覆盖4次的面积就能算出来了)
我们就可以开个线段树,segtree[rt][i]表示rt所表示的这个区间,覆盖i次的面积,因为题目要求是k次及以上,所以我们可以把k以上的都表示为k,这样计算答案的时候更方便
错误及反思:
uva是linux的,所以要lld代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int N =30005; vector<int> v; int segtree[N*8][11]; int lazy[N*8]; int T,n,k; struct LINE{ int x1,x2,y,flag; }line[N*2]; int get_id(int x){ return lower_bound(v.begin(),v.end(),x)-v.begin();} bool cmp(LINE w,LINE e){ return w.y<e.y;} void build(int l,int r,int rt) { segtree[rt][0]=v[r+1]-v[l]; if(l==r) return ; int m=(l+r)/2; build(lson); build(rson); } void pushup(int l,int r,int rt) { memset(segtree[rt],0,sizeof(segtree[rt])); if(l==r) segtree[rt][min(k,lazy[rt])]=v[r+1]-v[l]; else { for (int i = 0; i <= k; i++) segtree[rt][min(k,i+lazy[rt])] += segtree[rt<<1][i] + segtree[rt<<1|1][i]; } } void update(int L,int R,int v,int l,int r,int rt) { if(L<=l&&R>=r) { lazy[rt]+=v; pushup(l,r,rt); return ; } int m=(l+r)/2; if(L<=m) update(L,R,v,lson); if(R>m) update(L,R,v,rson); pushup(l,r,rt); } int main() { scanf("%d",&T); for(int I=1;I<=T;I++) { scanf("%d%d",&n,&k); for(int i=0;i<n;i++) { scanf("%d%d%d%d",&line[i*2].x1,&line[i*2].y,&line[i*2].x2,&line[i*2+1].y); line[i*2+1].y++; line[i*2].x2++; line[i*2+1].x1=line[i*2].x1; line[i*2+1].x2=line[i*2].x2; line[i*2].flag=1; line[i*2+1].flag=-1; v.push_back(line[i*2].x1); v.push_back(line[i*2].x2); } sort(line,line+n*2,cmp); sort(v.begin(),v.end()),v.erase(unique(v.begin(),v.end()),v.end()); memset(lazy,0,sizeof(lazy)); build(0,v.size()-1,1); long long ans=0; for(int i=0;i<n*2;i++) { if(i) ans+=1ll*(line[i].y-line[i-1].y)*segtree[1][k]; update(get_id(line[i].x1),get_id(line[i].x2)-1,line[i].flag,0,v.size()-1,1); } printf("Case %d: %lld\n",I,ans); v.clear(); } }
相关文章推荐
- UVA 11983 Weird Advertisement(线段树扫描线)
- UVA 11983 Weird Advertisement --线段树求矩形问题
- UVA 11983 Weird Advertisement(线段树求矩形并的面积)
- uva 11983 - Weird Advertisement(线段树)
- UVA 11983 - Weird Advertisement(线段树)
- UVA 11983 Weird Advertisement 线段树+离散化+扫描线
- UVA 11983 Weird Advertisement --线段树求矩形问题
- UVA - 11983 Weird Advertisement (线段树求并面积)
- 线段树扫描线uva11983
- [POJ1151]Atlantis(扫描线+线段树)
- HDU 1255 覆盖的面积 (线段树扫描线+面积交)
- ural1707 线段树扫描线
- UVa 11235 Frequent values / RMQ or 线段树
- BZOJ 2584: [Wc2012]memory(扫描线+线段树)
- 【BZOJ3958】[WF2011]Mummy Madness 二分+扫描线+线段树
- [UVA 11235]Frequent values[线段树区间查询]
- UVALive - 3938 (线段树,区间查询)
- hdu 1542 Atlantis(线段树+扫描线——面积并)
- UVa 11992 Fast Matrix Operations / 线段树成段更新
- UVa 12299 - RMQ with Shifts (简单线段树)