P9715 「QFOI R1」头

洛谷
P9715 「QFOI R1」头
题目链接

思路:

洛谷老传统了,喜欢卡常,正常的 O ( n l o g n ) O(nlogn) O(nlogn)好像会被卡。

就是个链表题,解法看第一篇题解就行了。这里查询用的不多,更多是删除,用set来实现双向链表是比较慢的 O ( n l o g n ) O(nlogn) O(nlogn)的所以被卡掉了,只有90pts,要满分就只能写模拟双链表优化为 O ( n + m + k ) O(n+m+k) O(n+m+k)的,第19个点600+ms,慢一点都不行。

code:

set版

模拟链表

#include <iostream>
#include <cstdio>
#include <set>
#include <list>
using namespace std;
const int maxn=2e6+5;
const int maxc=5e5+5;

int n,m,q,k;
long long color[maxc];

struct Data{
	int op,l,r,c;
	bool operator<(const Data &x)const{return true;}
};

struct Lst{
	int nxt[maxn];
	bool vis[maxn];
	int size;
	
	void mdy(int L,int R){
		int lst=0;
		for(int i=L;i<=R;i=nxt[i]){
			if(vis[i])continue;
			if(lst)nxt[lst]=nxt[R];
			lst=i;
			vis[i]=true;
			size--;
		}
	}
	int query(int L,int R){
		int cnt=0;
		for(int i=L;i<=R;i=nxt[i]){
			if(vis[i])continue;
			cnt++;
		}
		return cnt;
	}
}L,C;

void del(Lst &L,Lst &C,int l,int r,int c){
	color[c]+=1ll*L.query(l,r)*C.size;
	L.mdy(l,r);
}

Data opt1[maxn],opt2[maxn];
int main(){
//	cin>>n>>m>>k>>q;
	scanf("%d%d%d%d",&n,&m,&k,&q);
	int ct1=0,ct2=0;
	for(int i=1,op,l,r,c,t;i<=q;i++){
		scanf("%d%d%d%d%d",&op,&l,&r,&c,&t);
		if(t==1)opt1[++ct1]=Data{op,l,r,c};
		else opt2[++ct2]=Data{op,l,r,c};
	}
	for(int i=1;i<=n;i++)L.nxt[i]=i+1;
	L.size=n;
	for(int i=1;i<=m;i++)C.nxt[i]=i+1;
	C.size=m;
	int op,l,r,c;
	
	for(int i=ct1;i>=1;i--){
		op=opt1[i].op;
		l=opt1[i].l;
		r=opt1[i].r;
		c=opt1[i].c;
		if(op==1){
			color[c]+=1ll*L.query(l,r)*C.size;
			L.mdy(l,r);
		}
		else {
			color[c]+=1ll*C.query(l,r)*L.size;
			C.mdy(l,r);
		}
	}
	for(int i=1;i<=ct2;i++){
		op=opt2[i].op;
		l=opt2[i].l;
		r=opt2[i].r;
		c=opt2[i].c;
		if(op==1){
			color[c]+=1ll*L.query(l,r)*C.size;
			L.mdy(l,r);
		}
		else {
			color[c]+=1ll*C.query(l,r)*L.size;
			C.mdy(l,r);
		}
	}

	for(int i=1;i<=k;i++)
		printf("%lld ",color[i]);
	return 0;
}
  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值