每次区间染色,会删除若干个颜色段,添加 个颜色段。因此颜色段总数是 .
采用平衡树(用 set 即可)维护极长连续颜色段,维护每个颜色增加值大小的 ,并用树状数组维护每个点的答案减去对应颜色的 值。
Add
:直接给对应颜色的 进行修改。
Color
:当删除一个颜色段时,就将其区间加上原先颜色的 值;当添加一个颜色段时,就将其区间减去新颜色的 值(因为新颜色原先的 并没有加在这一段上,需要减去)。
Query
:输出答案即可,即树状数组维护的值加上对应颜色的 值。
不难发现树状数组操作次数和颜色段次数呈线性,时间复杂度 .
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<set>
#define pb emplace_back
#define mp std::make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef std::pair<int,int>pii;
typedef std::pair<ll,int>pli;
typedef std::pair<ll,ll>pll;
typedef std::vector<int>vi;
typedef std::vector<ll>vll;
template<typename T>T cmax(T &x, T y){return x=x>y?x:y;}
template<typename T>T cmin(T &x, T y){return x=x<y?x:y;}
template<typename T>
T &read(T &r){
r=0;bool w=0;char ch=getchar();
while(ch<'0'||ch>'9')w=ch=='-'?1:0,ch=getchar();
while(ch>='0'&&ch<='9')r=r*10+(ch^48),ch=getchar();
return r=w?-r:r;
}
template<typename T1,typename... T2>
void read(T1 &x, T2& ...y){ read(x); read(y...); }
const int N=1000010;
inline int lowbit(int x){return x&(-x);}
int n,q;
ll tree[N],tag[N];
void modify(int x,ll v){
for(;x<=n;x+=lowbit(x))tree[x]+=v;
}
void change(int x,int y,ll v){
modify(x,v);
if(y<n)modify(y+1,-v);
}
ll query(int x){
ll s=0;
for(;x;x-=lowbit(x))s+=tree[x];
return s;
}
struct Node{
int l,r,c;
Node(int x=0,int y=0,int z=0){
l=x;r=y;c=z;
}
bool operator < (const Node &x)const{
return l<x.l;
}
};
set<Node>st;
#define IT set<Node>::iterator
IT split(int pos){
auto it=st.lower_bound(Node(pos,pos,0));
if(it!=st.end()&&(*it).l==pos)return it;
--it;
int L=(*it).l,R=(*it).r,C=(*it).c;
st.erase(it);
st.insert(Node(L,pos-1,C));
return st.insert(Node(pos,R,C)).first;
}
void assign(int l,int r,int c){
auto itr=split(r+1),itl=split(l);
auto it=split(l);
for(;it!=itr;++it)
change((*it).l,(*it).r,tag[(*it).c]);
st.erase(itl,itr);
st.insert(Node(l,r,c));
change(l,r,-tag[c]);
}
int Col(int l,int r){
auto it=st.lower_bound(Node(l,r,0));
while(it==st.end()||(!(l>=(*it).l && r<=(*it).r)))--it;
return (*it).c;
}
signed main(){
#ifdef do_while_true
freopen("data.in","r",stdin);
#endif
read(n,q);
st.insert(Node(1,n,1));
while(q--){
char ch=getchar();while(ch!='C'&&ch!='A'&&ch!='Q')ch=getchar();
if(ch=='A'){
int c,x;read(c,x);
tag[c]+=x;
}
else if(ch=='Q'){
int x;read(x);
cout << query(x)+tag[Col(x,x)] << '\n';
}
else{
int l,r,c;read(l,r,c);
assign(l,r,c);
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
2020-02-16 CSP-J 2019游记