【CF1423G】Growing flowers

【CF1423G】Growing flowers

by AmanoKumiko

Description

维护一个长度为\(n\)的序列\(a\)\(m\)次操作

\(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

\(1\le n,m\le 10^5\)

Solution

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

考虑怎么解决查询的问题

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

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

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

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

那么只要维护出所有\(r-l\)的值的个数就行了

那么对于每个颜色开个\(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 @ 2022-03-18 10:35  冰雾  阅读(66)  评论(0编辑  收藏  举报