【CF1423G】Growing flowers
【CF1423G】Growing flowers
by AmanoKumiko
Description
维护一个长度为的序列,次操作
:把区间赋值为
:对于序列的每个长度为的子段,求出区间的不同颜色数然后加和输出
Input
第一行两个数
然后行读入操作
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
Solution
区间推平可以直接上珂朵莉树
考虑怎么解决查询的问题
我们从容斥的角度考虑这个问题
先假设每个子段拥有所有颜色
然后我们对每个颜色维护出它的所有位置
对于相邻的两个位置,我们要减去
那么只要维护出所有的值的个数就行了
那么对于每个颜色开个记录连续段
由于区间赋值均摊,所以直接暴力改的复杂度就是对的
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;
}
标签:
Codeforces
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话