bzoj 4548: 小奇的糖果 && bzoj 3658: Jabberwocky(双向链表+树状数组)
2017-08-12 02:33
281 查看
3658: Jabberwocky
Time Limit: 20 Sec Memory Limit: 1024 MBSubmit: 263 Solved: 107
[Submit][Status][Discuss]
Description
平面上有n个点,每个点有k种颜色中的一个。你可以选择一条水平的线段获得在其上方或其下方的所有点,如图所示:
![](http://www.lydsy.com/JudgeOnline/upload/201407/bb(1).jpg)
请求出你最多能够得到多少点,使得获得的点并不包含所有的颜色。
Input
包含多组测试数据,第一行输入一个数T表示测试数据组数。接下来T组测试数据,对于每组测试数据,第一行输入两个数n,k,分别表示点的个数和颜色数。
接下来n行每行描述一个点,前两个数z,y(lxl,lyl≤2^32-1)描述点的位置,最后一个数z(1≤z≤K)描述点的颜色。
Output
对于每组数据输出一行,每行一个数ans,表示答案。Sample Input
110 3
1 2 3
2 1 1
2 4 2
3 5 3
4 4 2
5 1 2
6 3 1
6 7 1
7 2 3
9 4 2
Sample Output
5将问题简化:
假设线段只有可能在在坐标系的最下面or最上面,并且每个x坐标都不同
那么只要用双向链表O(n)模拟一下就好了,所有坐标点按x大小排序,第p个节点就是从小到大第p个坐标
每个节点p记录一个p.pre和p.next,分别表示在左边or右边颜色相同且离得最近的节点id,
答案就是max(max(p.next-1-p, p-1-p.pre)) (1<=p<=n),也就是两个相邻的相同颜色节点之间距离的最大值
如果存在x坐标相同的点
要先将x坐标离散化,并且上面的那个式子就会有问题,因为x坐标相同的点只有可能同时取或同时不取
这样就不能直接求p.next和p的间隔了,而是找到x坐标刚好小于p.next点以及x坐标刚好大于p点的两点之间有多少个点,求这个的最大值,因为离散化过了,这个很好处理
p和p.pre之间同理
显然这题线段没有限制,不一定在最下面or最上面
那样的话我们需要按y坐标从小到大排序(如果相同再按x排序)
求出来上面的东西之后再从下到上扫描,逐个删点,每删一个点求一次最大值
因为是双向链表,所以删点是O(1)的,并且只有这段变大的区间会影响答案
不过因为中间有些点已经消失了,所以不能直接通过相减求间隔,要用树状数组保存哪些还没有被删
别忘了还要从上往下再来一次
总复杂度O(n)+O(2nlogn)=O(nlogn)
注意这题有个坑,假设有k种颜色但是下面出现的不同颜色数量都不到k个,那么答案就是n(也就是所有点全部选中)还有bzoj3658这题的数据比较强,虽然是一模一样的题,但一开始我4548AC了,3658WA,不是long long的问题
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define LL long long typedef struct { LL pre; LL nxt; }Line; Line h[100005]; typedef struct Res { LL x, y; LL id; LL col; bool operator < (const Res &b) const { if(id<b.id) return 1; return 0; } }Res; Res s[100005]; LL cnt, Hash[100005], tre[100005], temp[100005], y[100005], col[100005]; bool compx(Res a, Res b) { if(a.x<b.x) return 1; return 0; } bool compy(Res a, Res b) { if(a.y<b.y || a.y==b.y && a.x<b.x) return 1; return 0; } void Update(LL x, LL val) { while(x<=cnt) { tre[x] += val; x += x&-x; } } LL Query(LL x) { LL sum = 0; while(x) { sum += tre[x]; x -= x&-x; } return sum; } int main(void) { LL T, i, n, m, ans; scanf("%lld", &T); while(T--) { cnt = 0; scanf("%lld%lld", &n, &m); memset(col, 0, sizeof(col)); for(i=1;i<=n;i++) { scanf("%lld%lld%lld", &s[i].x, &s[i].y, &s[i].col); s[i].id = i; Hash[++cnt] = s[i].x; col[s[i].col] = 1; } for(i=1;i<=m;i++) { if(col[i]==0) break; } if(i<=m) { printf("%lld\n", n); continue; } sort(Hash+1, Hash+cnt+1); cnt = unique(Hash+1, Hash+cnt+1)-(Hash+1); s[n+1].x = cnt+1; for(i=1;i<=n;i++) s[i].x = lower_bound(Hash+1, Hash+cnt+1, s[i].x)-Hash; ans = 0; sort(s+1, s+n+1, compx); memset(temp, 0, sizeof(temp)); for(i=1;i<=n;i++) { Update(s[i].x, 1); h[i].pre = temp[s[i].col]; s[i].id = i; temp[s[i].col] = i; ans = max(ans, Query(s[i].x-1)-Query(s[h[i].pre].x)); } for(i=1;i<=n;i++) temp[i] = n+1; for(i=n;i>=1;i--) { h[i].nxt = temp[s[i].col]; temp[s[i].col] = i; ans = max(ans, Query(s[h[i].nxt].x-1)-Query(s[i].x)); } sort(s+1, s+n+1, compy); for(i=1;i<=n;i++) y[i] = s[i].id; sort(s+1, s+n+1); for(i=1;i<=n;i++) { Update(s[y[i]].x, -1); ans = max(ans, Query(s[h[y[i]].nxt].x-1)-Query(s[h[y[i]].pre].x)); h[h[y[i]].nxt].pre = h[y[i]].pre; h[h[y[i]].pre].nxt = h[y[i]].nxt; } sort(s+1, s+n+1, compx); memset(temp, 0, sizeof(temp)); for(i=1;i<=n;i++) { Update(s[i].x, 1); h[i].pre = temp[s[i].col]; s[i].id = i; temp[s[i].col] = i; ans = max(ans, Query(s[i].x-1)-Query(s[h[i].pre].x)); } for(i=1;i<=n;i++) temp[i] = n+1; for(i=n;i>=1;i--) { h[i].nxt = temp[s[i].col]; temp[s[i].col] = i; ans = max(ans, Query(s[h[i].nxt].x-1)-Query(s[i].x)); } sort(s+1, s+n+1, compy); for(i=1;i<=n;i++) y[i] = s[i].id; sort(s+1, s+n+1); for(i=n;i>=1;i--) { Update(s[y[i]].x, -1); ans = max(ans, Query(s[h[y[i]].nxt].x-1)-Query(s[h[y[i]].pre].x)); h[h[y[i]].nxt].pre = h[y[i]].pre; h[h[y[i]].pre].nxt = h[y[i]].nxt; } printf("%lld\n", ans); } return 0; }
相关文章推荐
- [乱搞 树状数组] BZOJ 4548 小奇的糖果 && BZOJ 3658 Jabberwocky
- 【BZOJ-4548&3658】小奇的糖果&Jabberwocky 双向链表 + 树状数组
- bzoj 4548: 小奇的糖果 双向链表+树状数组
- 【BZOJ4548】小奇的糖果
- bzoj 4548: 小奇的糖果(线段树+树状数组)
- [bzoj4548]【GDOI2018模拟7.14】小奇的糖果
- 【bzoj4548】小奇的糖果 STL-set+树状数组
- BZOJ 4548: 小奇的糖果 单调栈 链表+树状数组/主席树
- BZOJ4548 小奇的糖果
- 【BZOJ4548】小奇的糖果
- 【BZOJ4548】小奇的糖果 set(链表)+树状数组
- bzoj4548: 小奇的糖果
- bzoj4548: 小奇的糖果【链表+扫描线+树状数组】
- 【bzoj 4548】【JZOJ 5229】 小奇的糖果
- BZOJ 4548 小奇的糖果
- BZOJ 4548 小奇的糖果
- BZOJ3658 : Jabberwocky
- bzoj 2281: [Sdoi2011]黑白棋 && bzoj 4550: 小奇的博弈(Nimk博弈+DP)
- bzoj3293 [Cqoi2011]分金币&&bzoj1045 [HAOI2008]糖果传递
- bzoj3293 [Cqoi2011]分金币&&bzoj1045 [HAOI2008]糖果传递