「杂题乱刷」洛谷 P1558

好久没写 cnblog 了,来写一下。

做一下恢复训练。

P1558 (色板游戏)

数据结构板子题?反正我一开始是不知道怎么去维护的。

反正我代码分块写的跟线段树一样

思路大致是把图的颜色化成二进制,然后就很好做了,注意更新时记得顺便维护答案。

给大家几个样例来调代码:

hack1in:

100 30 2
C 1 86 1
P 87 86

hack1out:

1

hack2in:

100 30 6
C 1 100 2
C 1 95 1
C 1 90 3
P 95 90
P 96 91
P 96 90

hack2out:

2
2
3

参考代码:

点击查看代码
/*
Tips:
你数组开小了吗?
你MLE了吗?
你觉得是贪心,是不是该想想dp?
一个小时没调出来,是不是该考虑换题?
*/
#include<bits/stdc++.h>
using namespace std;
#define map unordered_map
#define forl(i,a,b) for(register long long i=a;i<=b;i++)
#define forr(i,a,b) for(register long long i=a;i>=b;i--)
#define lc(x) x<<1
#define rc(x) x<<1|1
#define cin(x) scanf("%lld",&x)
#define cout(x) printf("%lld",x)
#define lowbit(x) x&-x
#define pb push_back
#define pf push_front
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define endl '\n'
#define QwQ return 0;
#define ll long long
/*
Hack:
100 3 2
C 1 86 1
P 86 87
output:
1
*/
ll n,m,q,L,R,c,all[100010],a[100010],b[100010],ans[100010],l[100010],r[100010],sq;
char opt;
ll f(ll x){
	ll sum=0;
	for(;x;x-=lowbit(x))
		sum++;
	return sum;
}
void upd(ll x)
{
	ll sum=0;
	forl(i,l[x],r[x])
		sum|=a[i];
	ans[x]=sum;
}
void upd2(ll x)//第x个区间下传标记
{
	if(all[x]==0)
		return ;
	forl(i,l[x],r[x])
		a[i]=all[x];
	ans[x]=all[x],all[x]=0;
}
void add(ll L,ll R,ll c)
{
	if(b[L]==b[R])
	{
		upd2(b[L]);
		forl(i,L,R)
			a[i]=(1ll<<c);
		upd(b[L]);
		return ;
	}
	upd2(b[L]);
	forl(i,L,r[b[L]])
		a[i]=(1ll<<c);
	upd(b[L]);
	upd2(b[R]);
	forl(i,l[b[R]],R)
		a[i]=(1ll<<c);
	upd(b[R]);
	forl(i,b[L]+1,b[R]-1)
		all[i]=(1ll<<c),ans[i]=(1<<c);
}
void query(ll L,ll R)
{
	ll sum=0;
	if(b[L]==b[R])
	{
		upd2(b[L]);
		forl(i,L,R)
			sum|=a[i];
		cout<<f(sum)<<endl;
		return ;
	}
	upd2(b[L]);
	forl(i,L,r[b[L]])
		sum|=a[i];
	upd2(b[R]);
	forl(i,l[b[R]],R)
		sum|=a[i];
	forl(i,b[L]+1,b[R]-1)
		sum|=ans[i];
	cout<<f(sum)<<endl;
}
int main()
{
	IOS;
	cin>>n>>m>>q;
	sq=pow(sqrt(n),0.66);
	forl(i,1,n)
	{
		l[i]=r[i-1]+1;
		r[i]=min(sq*i,n);
		forl(j,l[i],r[i])
			b[j]=i,a[j]=(1ll<<1);
		all[i]=(1ll<<1),ans[i]=(1ll<<1);
	}
	while(q--)
	{
		cin>>opt>>L>>R;
		if(L>R)
			swap(L,R);
		if(opt=='C')
			cin>>c,add(L,R,c);
		else
			query(L,R);
	}
    /******************/
	/*while(L<q[i].l) */
	/*    del(a[L++]);*/
	/*while(L>q[i].l) */
	/*    add(a[--L]);*/
	/*while(R<q[i].r) */
	/*	  add(a[++R]);*/
	/*while(R>q[i].r) */
	/*    del(a[R--]);*/
    /******************/
	QwQ;
}
posted @ 2024-01-23 22:14  wangmarui  阅读(5)  评论(0编辑  收藏  举报