P9715 题解(2023 激励计划评分 7)
居然是赛场切掉的!
这里提供一个
给每种操作定义一个优先级。显然
而且第一种操作优先级显然大于第二种,这也是十分显然的。所以这里我设计的优先级是这样的:假设当前是第
然后考虑
保存所有操作的修改之后,可以将二维数组转化,将行、列的所有未被覆盖的操作按照从大到小的优先级排序,依次遍历,覆盖颜色。如果在遍历到某一行的时候,在之前覆盖了
这样复杂度就是
接下来考虑优化时间复杂度。分开记录行、列操作。处理行的时候,可以把每次操作的区间和优先级记录到一个 vector 里,维护一个优先队列(优先级从小到大排序),遍历
时间复杂度
顺带一提,由于使用了较多的 STL 数据结构,所以常数较大。所以遍历 vector 的时候建议使用 auto 遍历,读入输出使用较快方式,可以卡常数时间。
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
#define mpr make_pair
#define fr first
#define sc second
#define qwq pair<int,pair<pair<int,int>,int> >
char *p1,*p2,buf[100000];
#define nc() (p1==p2 && (p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)//快速读取字符
inline const int read(){//基于快读读取字符的超级快读
int x=0,f=1;register char ch=nc();
while (ch<48||ch>57) {if (ch=='-') f=-1;ch=nc();}
while (ch>=48&&ch<=57) x=x*10+ch-48,ch=nc();
return x*f;
}
const int n=read(),m=read(),k=read(),q=read();
int cnt1,cnt2;
long long sum[500005];
pair<int,int>opt1[2000005],opt2[2000005];
pair<pair<int,int>,int>qq[4000005];//{c,t},type
vector<pair<int,pair<int,int> > >op1[2000005],op2[2000005];//r,{c,t}
inline bool comp(const pair<pair<int,int>,int> &o,const pair<pair<int,int>,int> &p) {return o.fr.sc>p.fr.sc;}
void init1(){
priority_queue<qwq,vector<qwq >,less<qwq > >que;//t,{{l,r},c}
for (register int i=1;i<=n;++i){
while (!que.empty()){
if (que.top().sc.fr.sc<i) que.pop();
else break;
}
for (auto j:op1[i]) que.push(mpr(j.sc.sc,mpr(mpr(i,j.fr),j.sc.fr)));
if (!que.empty()){
const int col=que.top().sc.sc,tt=que.top().fr;
opt1[i]=mpr(col,tt);
}
}
}
void init2(){
priority_queue<qwq,vector<qwq >,less<qwq > >que;//t,{{l,r},c}
for (register int i=1;i<=m;++i){
while (!que.empty()){
if (que.top().sc.fr.sc<i) que.pop();
else break;
}
for (auto j:op2[i]) que.push(mpr(j.sc.sc,mpr(mpr(i,j.fr),j.sc.fr)));
if (!que.empty()){
const int col=que.top().sc.sc,tt=que.top().fr;
opt2[i]=mpr(col,tt);
}
}
}
int main(){
int op,l,r,c,t,ggg;
for (register int i=1;i<=q;++i){
op=read(),l=read(),r=read(),c=read(),t=read(),ggg=(t==1?i:-i);
if (op==1) op1[l].push_back(mpr(r,mpr(c,ggg)));
else op2[l].push_back(mpr(r,mpr(c,ggg)));
}
init1(),init2();
for (register int i=1;i<=n;++i) qq[i]=mpr(opt1[i],1);
for (register int i=1;i<=m;++i) qq[n+i]=mpr(opt2[i],2);
sort(qq+1,qq+n+m+1,comp);
for (register int i=1;i<=n+m;++i){
int col=qq[i].fr.fr,typ=qq[i].sc;
if (col==0) continue;
if (typ==1) ++cnt1,sum[col]+=m-cnt2;
else ++cnt2,sum[col]+=n-cnt1;
}
for (register int i=1;i<=k;++i) printf("%lld ",sum[i]);
return 0;
}