【bzoj 4548】【JZOJ 5229】 小奇的糖果
2017-07-14 20:52
351 查看
Description
有 N 个彩色糖果在平面上。小奇想在平面上取一条水平的线段,并拾起它上方或下方的所有糖果。求出最多能够拾起多少糖果,使得获得的糖果不包含所有的颜色。对于 30% 的数据,N ≤ 100;
对于 60% 的数据,N ≤ 5000;
对于 100% 的数据,N ≤ 100000,K ≤ 100000,T ≤ 3。
Preface
比赛的时候一直以为是分治+数据结构套路题,不敢打正解却是乱搞,说明不可陷入惯性思维,看起来类似的题,解法也可能大相径庭
30%
枚举线段两个端点,再O(n)按从上到下或从下到上的顺序扫描每一个点判断O(n^3)
60%
正解写炸的不知道有什么O(n^2logn)的做法,也不知道能不能过这一档
100%
考虑一个合法且尽量优的矩阵满足什么条件其左右边界肯定顶着一对相同的颜色(被该颜色卡住而不能继续扩展)
方便叙述,此处只讨论在选择线段上方的情况
假若维护一条水平线,表示线段高度
水平线从下往上扫,线段的两个端点显然会不断往两边扩展
如果扫的时候遇到一个点,其颜色为x,那么它的贡献是什么?
那么这个点被删除,之后该颜色的限制放宽
其它线段的端点原本被该点卡住,现在可以扩展了,需要更新,可以用双向链表维护
同时为了查询区域点数,使用树状数组维护
从上往下扫类似
O(nlogn)
Think Further
考虑类似问题:同样是线段上方或下方,求最少包含多少个点,使得包含所有颜色?大致idea:维护水平线扫描,同时不断将线段两端收紧
Code
#include<cstdio> #include<cstring> #include<algorithm> #define fo(i,a,b) for(int i=a;i<=b;i++) #define fd(i,a,b) for(int i=a;i>=b;i--) #define min(x,y) ((x)<(y)?(x):(y)) #define max(x,y) ((x)>(y)?(x):(y)) using namespace std; typedef long long ll; const int N=1e5+5; void read(int &t) { t=0; int p=1;char ch; for(ch=getchar();ch<'0' || ch>'9';ch=getchar()) if(ch=='-') p=-1; for(;'0'<=ch && ch<='9';ch=getchar()) t=t*10+ch-'0'; t*=p; } int n,m,num,ans,x ,jx ,jy ,c ,tr ,last ,L ,R ; struct node { int x,y,z,id; }a ,b ; bool cmpx(node a,node b){return a.x<b.x;} bool cmpy(node a,node b){return a.y<b.y;} int lowbit(int x){return x&-x;} void add(int x,int z) { for(;x<=n;x+=lowbit(x)) tr[x]+=z; } int query(int x) { int t=0; for(;x;x-=lowbit(x)) t+=tr[x]; return t; } int get(int l,int r) { return query(r)-query(l-1); } void solve() { memset(last,0,sizeof(last)); sort(a+1,a+n+1,cmpx); fo(i,1,n) add(a[i].x,1); fo(i,1,n) { int id=a[i].id,lst=last[a[i].z]; L[id]=lst,R[id]=n+1; if(lst) R[lst]=id; ans=max(ans,get(x[lst]+1,x[id]-1)); last[a[i].z]=id; } fo(i,1,m) ans=max(ans,get(x[last[i]]+1,n)); sort(a+1,a+n+1,cmpy); int lst=1; for(int i=1,j=1;i<=n;i++) { int id=a[i].id; for(;j<=n && a[j].y==a[i].y;j++) add(a[j].x,-1); L[R[id]]=L[id],R[L[id]]=R[id]; ans=max(ans,get(x[L[id]]+1,x[R[id]]-1)); } } int main() { int _; for(read(_);_;_--) { memset(a,0,sizeof(a)); ans=0; read(n);read(m); fo(i,1,n) read(a[i].x),read(a[i].y),read(a[i].z),a[i].id=i,jx[i]=a[i].x; sort(jx+1,jx+n+1); fo(i,1,n) x[i]=a[i].x=lower_bound(jx+1,jx+n+1,a[i].x)-jx; x[n+1]=n+1; solve(); fo(i,1,n) a[i].y=-a[i].y; solve(); printf("%d\n",ans); } return 0; }
相关文章推荐
- 【BZOJ4548】小奇的糖果
- 【JZOJ 5229】【GDOI2018模拟7.14】小奇的糖果
- bzoj 4548: 小奇的糖果(线段树+树状数组)
- BZOJ 4548: 小奇的糖果 单调栈 链表+树状数组/主席树
- BZOJ 4548 小奇的糖果
- 【bzoj4548】小奇的糖果 STL-set+树状数组
- bzoj 4548: 小奇的糖果 双向链表+树状数组
- BZOJ4548 小奇的糖果
- [乱搞 树状数组] BZOJ 4548 小奇的糖果 && BZOJ 3658 Jabberwocky
- bzoj4548: 小奇的糖果
- BZOJ 4548 小奇的糖果
- [JZOJ5229] 小奇的糖果
- bzoj4548: 小奇的糖果【链表+扫描线+树状数组】
- 【BZOJ4548】小奇的糖果 set(链表)+树状数组
- [bzoj4548]【GDOI2018模拟7.14】小奇的糖果
- bzoj 4548: 小奇的糖果 && bzoj 3658: Jabberwocky(双向链表+树状数组)
- 【JZOJ5229】【GDOI2018模拟7.14】小奇的糖果
- 【BZOJ4548】小奇的糖果
- 【BZOJ-4548&3658】小奇的糖果&Jabberwocky 双向链表 + 树状数组
- BZOJ3052: [wc2013]糖果公园