E. Colorful Operations
对于一个序列 有三种操作:
1.将[l,r]区间颜色修改为c
2.将所有c颜色的+x
3.单点查询
操作1好说是个区间修改 操作2就有点逆天了 那我们考虑简化操作2 我们可以列一个数组color 每次操作2 就相当于color[c]+=x;
那么我们操作1 自然在修改的时候就要 加上当前c的再减去改后c的color里面的值即可
但是这个区间修改1 可以想到不是普通的线段树区间修改 他要是颜色不同的话 会递归到最下面 而且会有很多区间
但是他最多的区间产生就是m个 这样想岂不是qmlogm 其实不然 他每次到达m后 要是做一次就会回归1 所以总和不会超过2m 时间复杂度是O(q+qlogm)
注意我们修改时必须要修改same==1的区间
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6+10;
const int M = 998244353;
const int mod = 998244353;
#define int long long
#define endl '\n'
#define Endl '\n'
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
#define _ 0
#define inf 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
#define ls (2*rt)
#define rs (2*rt + 1)
struct node{
int l,r,same,lz,col;
}tree[N<<2];
int color[1000010],ans;
void pushup(node &u,node &l,node &r){
if(l.col==r.col&&l.same&&r.same){
u.same=1;
u.col=l.col;
}else u.same=0;
}
inline void pushup(int u){
pushup(tree[u],tree[u<<1],tree[u<<1|1]);
}
void pushdown(int i){
if(tree[i].same!=0){
tree[i<<1].lz+=tree[i].lz,tree[i<<1|1].lz+=tree[i].lz;//我们只用单点查询 所以不用保证中间节点的正确性
tree[i<<1].col=tree[i].col,tree[i<<1|1].col=tree[i].col;
tree[i].lz=0;
}
}
inline void build(int i,int l,int r){
tree[i].l=l;tree[i].r=r;
if(l==r){
tree[i].col=tree[i].same=1;
return ;
}
int mid=l+r>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
pushup(i);
}
void modify(int i,int l,int r,int k){
if(tree[i].r<=r && tree[i].l>=l&&tree[i].same){
tree[i].lz += color[tree[i].col];
tree[i].col = k;
tree[i].lz -= color[tree[i].col];
return ;
}
pushdown(i);
if(tree[i<<1].r>=l)modify(i<<1,l,r,k);
if(tree[i<<1|1].l<=r)modify(i<<1|1,l,r,k);
pushup(i);
}
inline node query(int i,int l,int r){
//if(l>r)return{0};
node s;
if(tree[i].l>=l && tree[i].r<=r){
ans=color[tree[i].col];
return tree[i];
}
pushdown(i);
if (tree[i<<1].r>=r) s= query(i<<1,l,r);
else if(tree[i<<1|1].l<=l) s= query(i<<1|1,l,r);
else{
auto left = query(i<<1,l,r);
auto right= query(i<<1|1,l,r);
node res;
pushup(res,left,right);
return res;
}
return s;
}
void solve() {
int n,m;cin>>n>>m;
build(1,1,n);
while(m--){
char op[10];cin>>op;
if(op[0]=='C'){
int l,r,k;cin>>l>>r>>k;
modify(1,l,r,k);
}else if(op[0]=='A'){
int x,k;cin>>x>>k;
color[x]+=k;
}else{
int x;cin>>x;
cout<<query(1,x,x).lz+ans<<endl;
}
}
}
signed main(){
fast
int T;T=1;
while(T--) {
solve();
}
return ~~(0^_^0);
}
标签:771,int,tree,Codeforces,cin,color,op,Round,define
From: https://www.cnblogs.com/ycllz/p/16656080.html