P2787求卡常
  • 板块学术版
  • 楼主yinbe
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/12/29 22:44
  • 上次更新2023/12/30 10:59:01
查看原帖
P2787求卡常
759152
yinbe楼主2023/12/29 22:44

题目传送门

#include<iostream>
#include<set>
#include<cstring>
using namespace std;
int n,m;
char c[100005];
inline int read()
{
    register int x=0;
	register char ch=getchar();
    while(ch<'0'||ch>'9'){ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^'0');ch=getchar();}
    return x;
}
struct tree
{
	int l,r;
	mutable int v;
	bool operator<(const tree &o)const
	{
		return l<o.l;
	}
};
set<tree>t;
inline auto split(int m)
{
	auto it=t.upper_bound({m,0,0});
	it--;
	if(it->l==m)return it;
	int l=it->l,r=it->r,v=it->v;
	t.erase(it);
	t.insert({l,m-1,v});
	return t.insert({m,r,v}).first;
}
inline void assign(int l,int r,int v)
{
	auto itr=split(r+1);
	auto itl=split(l);
	t.erase(itl,itr);
	t.insert({l,r,v});
	return;
}
inline int ask(int l,int r,int v)
{
	int cnt=0;
	auto itr=split(r+1);
	auto itl=split(l);
	for(auto it=itl;it!=itr;it++)
	{
		if(it->v==v)
		{
			cnt+=it->r-it->l+1;
		}
	}
	return cnt;
}
inline void sort(int l,int r)
{
	int a[30];
	memset(a,0,sizeof(a));
	auto itr=split(r+1);
	auto itl=split(l);
	while(itl!=itr)
	{
		a[itl->v]+=itl->r-itl->l+1;
		itl=t.erase(itl);
	}
	for(int i=1;i<=26;i++)
	{
		if(a[i])
		{
			t.insert({l,l+a[i]-1,i});
			l+=a[i];
		}
	}
	return;
}
int main()
{
	n=read();m=read();
	scanf("%s",c+1);
	char last=toupper(c[1]);
	c[1]=toupper(c[1]);
	int cnt=1;
	for(int i=2;i<=n;++i)
	{
		c[i]=toupper(c[i]);
		if(c[i]==last)
		{
			++cnt;
		}			
		else
		{
			t.insert({i-cnt,i-1,last-'A'+1});
			last=c[i];
			cnt=1;
		}
	}
	t.insert({n+1-cnt,n,last-'A'+1});
	t.insert({n+1,n+1,0});
	while(m--)
	{
		int flag,l,r;
		flag=read();l=read();r=read();
		if(flag==1)
		{
			char k;
			scanf(" %c",&k);
			printf("%d\n",ask(l,r,toupper(k)-'A'+1));
		}
		else if(flag==2)
		{
			char k;
			scanf(" %c",&k);
			assign(l,r,toupper(k)-'A'+1);
		}
		else
		{
			sort(l,r);
		}
	}
	return 0;
}
2023/12/29 22:44
加载中...