codeforces 983D
Posted yuhuger
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces 983D相关的知识,希望对你有一定的参考价值。
这题题意非常清真。
给你一个二维平面,初始颜色为0,第i操作给一个矩形涂上i颜色,问最后可见颜色数量。
第一眼感觉是二维线段树,
但是二维线段树真的可以矩形加,矩形查询并保证复杂度吗???
我并不会。
于是前去学习题解。
题解非常详细:
1.离线修改,扫描x轴,维护y轴上的线段树
2.线段树的每个节点维护三个对象,
第一个是一个set,表示修改时拆到改区间上的颜色集合
第二个是max,表示最大可见元素(若没有为0)。
第三个是min,是维护max用的,可以理解为max至少是多少。
3.重点是pushup
如果是叶子节点,如果该最大set元素没有出现过,max=max_element(set),min=0,
否则max=0,min=max_element(set)
如果是非叶,max对左右孩子取max,min对左右孩子取min(显然,你在左右孩子中任意一个露出来就可以了)
照例用该节点set最大值没出现过更新max,出现过更新min。
如果这个节点的max甚至没达到min的标准,那么就没有任何一种新的露出颜色。
感觉说的很不清楚,还是看代码吧~
#include <bits/stdc++.h> using namespace std; const int N=100010; const int P=540000; set<int> s[P]; int ll,rr,vv,mx[P],mi[P]; int a[N],b[N],c[N],d[N]; bool del[N]; #define M int mid=(l+r)>>1 #define L (ind<<1,l,mid) #define R (ind<<1|1,mid+1,r) void up(int ind,int l,int r){ if (l^r){ mx[ind]=max(mx[ind<<1],mx[ind<<1|1]); mi[ind]=min(mi[ind<<1],mi[ind<<1|1]); } else mx[ind]=mi[ind]=0; if (s[ind].size()){ int tmp=*s[ind].rbegin(); if (del[tmp]) mi[ind]=max(mi[ind],tmp); else mx[ind]=max(mx[ind],tmp); } if (mx[ind]<mi[ind]) mx[ind]=0; } void modify(int ind,int l,int r){ if (ll<=l&&r<=rr){ if (vv>0){ s[ind].insert(vv); } else if (vv<0) s[ind].erase(-vv); up(ind,l,r); return; } M; if (ll<=mid) modify L; if (mid<rr) modify R; up(ind,l,r); } map<int,int> mpx,mpy; vector<int> e[N+N]; int main(){ ios::sync_with_stdio(0); int n; cin>>n; for (int i=1; i<=n; ++i){ cin>>a[i]>>b[i]>>c[i]>>d[i]; mpx[a[i]]=1; mpy[b[i]]=1; mpx[c[i]]=1; mpy[d[i]]=1; } int szx=0,szy=0; for (map<int,int>::iterator it=mpx.begin(); it!=mpx.end(); ++it){ it->second=++szx; } for (map<int,int>::iterator it=mpy.begin(); it!=mpy.end(); ++it){ it->second=++szy; } for (int i=1; i<=n; ++i){ a[i]=mpx[a[i]],b[i]=mpy[b[i]],c[i]=mpx[c[i]],d[i]=mpy[d[i]]-1; e[a[i]].push_back(i); e[c[i]].push_back(i); } int ans=1; for (int i=1; i<=szx; ++i){ for (auto j:e[i]){ ll=b[j]; rr=d[j]; vv=(i==a[j]?j:-j); modify(1,1,szy); } while (mx[1]){ ++ans; del[mx[1]]=1; ll=b[mx[1]]; rr=d[mx[1]]; vv=0; modify(1,1,szy); } } cout<<ans; }
以上是关于codeforces 983D的主要内容,如果未能解决你的问题,请参考以下文章
[Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3)][C. Playing Piano](代码片段
Codeforces 86C Genetic engineering(AC自动机+DP)
CodeForces 1005D Polycarp and Div 3(思维贪心dp)