最新文章
这里会显示最新的几篇文章摘要。
记录生活,分享知识,与你一起成长。
这里会显示最新的几篇文章摘要。
在古希腊的神话中,有一位掌管刷墙的神。他面前有一面大小为n*m的白墙,他有k+1种颜料(白色为 0 号,其他颜色分别为 1 到 k)。神将进行q次粉刷操作,每次使用宽度为 1 单位的刷子,染色后覆盖一整行或者一整列。现在给出他的所有操作,你能告诉他,除白色外,每种颜色的最后覆盖面积吗?
第一行包含四个整数n,m,k,q。
接下来q行描述q次粉刷操作。
每行包含三个正整数opt,u,c:
输出一行包含k个整数,分别表示每种颜色的最终覆盖面积。
5 5 2 2
1 1 1
0 1 2
4 5
对于30%的数据,满足n≤100,0≤q≤100
对于50%的数据,满足n≤5000,0≤q≤5000
对于100%的数据,满足n,m≤10^5, q≤10^5, 0≤k≤10^5
题意是统计经过q次粉刷过后墙壁每个颜色的个数,怎么统计最后的颜色,遍历的话会超时,因此考虑二分查找哪些区块的粉刷时间比较早,比较早的会被当前的颜色覆盖掉。
分别记录行和列的颜色和粉刷次序,对粉刷次序进行排序,统计第i列的颜色的时候,第i列里每一个行的粉刷次序比较早的就会被记为一个。
struct cow {
int id = 0;
int val;
bool operator < (const cow& a) const {
return id < a.id;
}
};
cow c[100005],r[100005]; //行和列
int idx; //记录次序
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
//
// freopen("E:/Code/C++/untitled1/input.txt","r",stdin);
// freopen("output.txt","w",stdout);
int n, m, k, q;
cin >> n >> m >> k >> q;
while (q--) {
int o, u, p;
cin >> o >> u >> p;
if (o==1) {
c[u].val = p; //列粉刷
c[u].id = ++idx;
}
else {
r[u].val = p;
r[u].id = ++idx;
}
}
sort(c+1,c+1+n); //对行列排序
sort(r+1,r+1+m);
vector<int> color(k+1);
for (int i = 1;i <= n;++i) { //对统计行颜色
if (r[i].id == 0) continue;
auto it = lower_bound(c+1,c+m+1,r[i]) - (c+1); //比该行颜色粉刷早的个数
color[r[i].val] += it;//de(it);
}
for (int i = 1;i <= m;++i) { //对列统计
if (c[i].id == 0) continue;
auto it = lower_bound(r+1,r+1+m,c[i]) - (r+1);
color[c[i].val] += it;
}
for (int i = 1;i <= k;++i) cout << color[i] << ' ';
}