【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;
}

浙公网安备 33010602011771号