bzoj 4548 小奇的糖果

树状数组.

  • 题面有些歧义,线段上/下方的点是指横坐标也落在线段范围内的点.不包含所有颜色是指不包含所有 $k$ 种颜色.
  • 要求不包含所有颜色,即至少有一种颜色没有包含.可以枚举这个颜色 $c$ ,计算不包含 $c$ 时的最大收益.
  • 把所有点按照 $y$ 坐标从小到大排序,依次处理.如果对某一个点,以它的 $y$ 坐标为下边界画矩形,贪心画最大的,往两边拓展,直到遇到不能选的颜色为止.这个就是在对应颜色的 $set$ 里面找一下前驱后继.
  • 以它的 $y$ 坐标为上边界同理,将 $y$ 坐标从大到小排序做上面过程即可.画矩形时的收益用树状数组维护.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline int read()
{
int out=0,fh=1;
char jp=getchar();
while ((jp>'9'||jp<'0')&&jp!='-')
jp=getchar();
if (jp=='-')
fh=-1,jp=getchar();
while (jp>='0'&&jp<='9')
out=out*10+jp-'0',jp=getchar();
return out*fh;
}
const int MAXN=1e5+10;
struct node
{
int x,y,col;
bool operator < (const node &rhs) const
{
return y<rhs.y;
}
}a[MAXN];
int n,m,ans=0,v[MAXN];
struct FenwickTree
{
int bit[MAXN];
void init(){memset(bit,0,sizeof bit);}
#define lowbit(x) x&(-x)
void add(int x,int c)
{
for(;x<=n;x+=lowbit(x))
bit[x]+=c;
}
int sum(int x)
{
int s=0;
for(;x;x-=lowbit(x))
s+=bit[x];
return s;
}
}T;
set<int> s[MAXN];
set<int>::iterator it;
void solve()
{
T.init();
for(int i=1;i<=m;++i)
{
s[i].clear();
s[i].insert(0);
s[i].insert(n+1);
}
for(int i=1,j=1;i<=n;i=j)
{
while(j<=n && a[j].y==a[i].y)
++j;
for(int k=i;k<j;++k)
{
int tmp=T.sum(*s[a[k].col].lower_bound(a[k].x)-1);
tmp-=T.sum(*--s[a[k].col].upper_bound(a[k].x));
ans=max(ans,tmp);
}
for(int k=i;k<j;++k)
{
T.add(a[k].x,1);
s[a[k].col].insert(a[k].x);
}
}
for(int i=1;i<=m;++i)
for(it=s[i].begin();*it!=n+1;)
{
int j=*it;
++it;
ans=max(ans,T.sum(*it-1)-T.sum(j));
}
}
int main()
{
int C=read();
while(C--)
{
n=read(),m=read();
for(int i=1;i<=n;++i)
{
a[i].x=read();
a[i].y=read();
a[i].col=read();
v[i]=a[i].x;
}
sort(a+1,a+1+n);
sort(v+1,v+1+n);
int cnt=unique(v+1,v+1+n)-v-1;
for(int i=1;i<=n;++i)
a[i].x=lower_bound(v+1,v+1+cnt,a[i].x)-v;
ans=0;
solve();
for(int i=1;i*2<=n;++i)
swap(a[i],a[n+1-i]);
solve();
cout<<ans<<endl;
}
return 0;
}