【CF1423G】Growing flowers

【CF1423G】Growing flowers

by AmanoKumiko

Description

维护一个长度为n的序列am次操作

1,l,r,x:把区间[l,r]赋值为x

2,k:对于序列的每个长度为k的子段,求出区间的不同颜色数然后加和输出

Input

第一行两个数n,m

然后m行读入操作

Output

每次询问输出一行一个数表示答案

Sample Input

5 5
1 2 3 4 5
2 3
1 1 2 5
2 4
1 2 4 5
2 2

Sample Output

9
6
4

Data Constraint

1n,m105

Solution

区间推平可以直接上珂朵莉树

考虑怎么解决查询的问题

我们从容斥的角度考虑这个问题

先假设每个子段拥有所有颜色

然后我们对每个颜色维护出它的所有位置

对于相邻的两个位置l,r,我们要减去max(0,rlk)

那么只要维护出所有rl的值的个数就行了

那么对于每个颜色开个set记录连续段

由于区间赋值均摊O(n+m),所以直接暴力改的复杂度就是对的

Code

#include<bits/stdc++.h>
using namespace std;
#define F(i,a,b) for(int i=a;i<=b;i++)
#define Fd(i,a,b) for(int i=a;i>=b;i--)
#define LL long long
#define N 100010

int n,m,a[N];
struct node{
	int l,r,val;
	node(int a=-1,int b=-1,int c=0){l=a;r=b;val=c;}
	bool operator<(const node&x)const{return l<x.l;}
};
set<node>s;
set<node>col[N];
struct tree{
	LL sum1[N],sum2[N];
	int lowbit(int x){return -x&x;}
	void modify(int x,LL y,LL z){for(;x<=n+1;x+=lowbit(x))sum1[x]+=y,sum2[x]+=z;}
	LL qur1(int x){LL res=0;for(;x;x-=lowbit(x))res+=sum1[x];return res;}
	LL qur2(int x){LL res=0;for(;x;x-=lowbit(x))res+=sum2[x];return res;}
}t;

set<node>::iterator split(int pos){
	auto it=s.lower_bound(node(pos));
	if(it!=s.end()&&it->l==pos)return it;
	it--;node tmp=*it;
	col[tmp.val].erase(tmp);
	col[tmp.val].insert(node(tmp.l,pos-1,tmp.val));
	col[tmp.val].insert(node(pos,tmp.r,tmp.val));
	s.erase(it);
	s.insert(node(tmp.l,pos-1,tmp.val));
	return s.insert(node(pos,tmp.r,tmp.val)).first;
}

void del(node x){
	int nxt=col[x.val].upper_bound(x)->l;
	auto it=col[x.val].lower_bound(x);it--;
	int lst=it->r;
	t.modify(nxt-x.r,-(nxt-x.r),-1);
	t.modify(x.l-lst,-(x.l-lst),-1);
	t.modify(nxt-lst,nxt-lst,1);
	col[x.val].erase(x);
}

void ins(node x){
	int nxt=col[x.val].upper_bound(x)->l;
	auto it=col[x.val].lower_bound(x);it--;
	int lst=it->r;
	t.modify(nxt-x.r,nxt-x.r,1);
	t.modify(x.l-lst,x.l-lst,1);
	t.modify(nxt-lst,-(nxt-lst),-1);
	col[x.val].insert(x);
}

void assign(int l,int r,int val){
	auto itr=split(r+1),itl=split(l);
	for(auto it=itl;it!=itr;++it)del(*it);
	s.erase(itl,itr);
	node tmp=node(l,r,val);
	ins(tmp);s.insert(tmp);
}

int main(){
	scanf("%d%d",&n,&m);
	F(i,1,N-10){
		col[i].insert(node(0,0));
		col[i].insert(node(n+1,n+1));
		t.modify(n+1,n+1,1);
	}
	F(i,1,n){
		scanf("%d",&a[i]);
		s.insert(node(i,i,a[i]));
		ins(node(i,i,a[i]));
		col[a[i]].insert(node(i,i));
	}
	F(i,1,m){
		int op,l,r,x;
		scanf("%d",&op);
		if(op==1){
			scanf("%d%d%d",&l,&r,&x);
			assign(l,r,x);
		}else{
			scanf("%d",&x);
			printf("%lld\n",1ll*(N-10)*(n-x+1)-(t.qur1(n+1)-t.qur1(x-1))+(t.qur2(n+1)-t.qur2(x-1))*x);
		}
	}
	return 0;
}
posted @   冰雾  阅读(73)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示