简要题意:
1. 每次给
(x,y)
染上颜色
c
。
2. 询问
对于一个修改能够影响的询问,是在这个修改之后的所有
x
坐标大于当前修改位置的询问。
每次询问需要回答的就是
现在问题已经简化成了,每次给一点染若干次色,问区间内有多少种颜色。
颜色数目只有
50
个, 考虑压位线段树来快速查询。
因为时间本身是有序的,这样就保持了第一维有序。然后我们用cdq分治处理
x
坐标这一维,用线段树维护
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL maxn = 160000;
LL t;
struct ASK {
LL x, y, y1, y2, c, t, type;
bool operator < (const ASK & b)const {
return x < b.x;
}
};
vector<ASK> _ask(maxn);
ASK askl[maxn], askr[maxn];
LL ans[maxn];
struct Seg{
LL val;
} tr[4100000];
void pushup(LL rt) {
tr[rt].val = tr[rt<<1].val | tr[rt<<1|1].val;
}
void update(LL p, LL c, LL l, LL r, LL rt, LL tag) {
if(l == r) {
if(tag)
tr[rt].val |= (1LL << c);
else
tr[rt].val = 0;
return ;
}
LL m = (l + r) >> 1;
if(p <= m) update(p, c, l, m, rt<<1, tag);
else update(p, c, m+1, r, rt<<1|1, tag);
pushup(rt);
}
LL ask(LL L, LL R, LL l, LL r, LL rt) {
if(L <= l && R >= r)
return tr[rt].val;
LL m = (l + r) >> 1;
LL res = 0;
if(L <= m) res |= ask(L, R, l, m, rt<<1);
if(R > m) res |= ask(L, R, m+1, r, rt<<1|1);
pushup(rt);
return res;
}
LL bitcount(LL x) {
return x == 0?0:x%2+bitcount(x/2);
}
void cdq(LL l, LL r) {
if(l == r) return ;
LL m = l + r >> 1;
cdq(l, m);
LL cl = 0, cr = 0;
for(LL i = l; i <= m; i++)
askl[cl++] = _ask[i];
for(LL i = m+1; i <= r; i++)
askr[cr++] = _ask[i];
sort(askl, askl+cl);
sort(askr, askr+cr);
LL i = 0;
for(LL j = 0; j < cr; j++) {
if(askr[j].type == 2) {
while(askr[j].x >= askl[i].x && i < cl) {
if(askl[i].type == 1)
update(askl[i].y, askl[i].c, 1, 1000000, 1, 1);
i++;
}
ans[askr[j].t] |= ask(askr[j].y1, askr[j].y2, 1, 1000000, 1);
}
}
for(LL _ = 0; _ < i; _++)
if(askl[_].type == 1)
update(askl[_].y, askl[_].c, 1, 1000000, 1, 0);
cdq(m+1, r);
}
int main() {
LL o;
scanf("%lld", &o);
for(;;) {
if(o == 3) break;
t = 0;
for(;;) {
scanf("%lld", &o);
if(o == 1) {
scanf("%lld%lld%lld", &_ask[t].x, &_ask[t].y, &_ask[t].c);
_ask[t].t = t;
_ask[t].type = 1;
t++;
} else if(o == 2) {
scanf("%lld%lld%lld", &_ask[t].x, &_ask[t].y1, &_ask[t].y2);
_ask[t].t = t;
_ask[t].type = 2;
t++;
} else break;
}
cdq(0, t-1);
for(LL i = 0; i < t; i++) {
if(_ask[i].type == 2)
printf("%lld\n", bitcount(ans[i])), ans[i] = 0;
}
}
return 0;
}