颜色段均摊/珂朵莉树
(哪个天才想出珂朵莉树这种名字的)
一般颜色段都使用set来维护,记录颜色段左右端点以及区间的值,一般还有时间戳一类的东西。
其优点是按顺序自动排序、插入删除方便,可以快速找到相邻的颜色段,通过lower_bound之类的快速查找特定左右端点颜色段。
颜色段均摊则是指维护某种区间推平操作复杂度为 \(O(n\log n)\) 的算法。
可以发现每次推平操作最多新增加3个颜色段(将包含新插入颜色段的左右端点的旧颜色段切断),而每一个颜色段被插入之后会遍历其所覆盖的颜色段,统计这一段的信息,删除其贡献,然后被覆盖的这些颜色段就会被新插入的这个颜色段覆盖。
所以每一个颜色段最多被插入一次、被覆盖一次,因此复杂度是 \(O(\omega n)\) 的。其中 \(n\) 是颜色段数量,\(\omega\) 是查找并处理一个颜色段的复杂度。
也就是说如果我们能够快速查找并处理颜色段,那就可以做到处理区间推平的复杂度正确了。显然set本身就可以达到要求。
P8512 [Ynoi Easy Round 2021] TEST_152
显然先把询问离线下来固定右端点做扫描线。
考虑到只有区间推平一种操作,因此直接用颜色段均摊。
对于每个右端点,将前面的操作都做了。由于对于一个固定的 \(r\),查询都是一个后缀,因此我们只需要给每一个区间都打上时间戳,即其原始右端点。
查询时间戳比当前询问的左端点大的就可以了。因为时间戳比左端点小的对于这个询问来说是不存在的,直接无视就可以了。
然后就发现这是一个单点修改,区间求和。然后就树状数组了。
然后就是比较模板的维护颜色段了。
code
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IT set<node>::iterator
const int N=1e6+7;
int n,m,qq,ql[N],qr[N],qv[N],tr[N],ans[N];
struct node{int l,r,v,t;};
struct edge{int l,r,id;}que[N];
bool cmp(edge x,edge y){return x.r<y.r;}
bool operator < (node x,node y){return x.r<y.r;}
set <node> s;
void add(int x,int val){while(x<=n&&x)tr[x]+=val,x+=x&(-x);}
int query(int x){int res=0;while(x)res+=tr[x],x-=x&(-x);return res;}
void split(IT a,int x)
{
int l=a->l,r=a->r,v=a->v,t=a->t;
if(x<l||x>=r) return;
s.erase(a),s.insert({l,x,v,t}),s.insert({x+1,r,v,t});
}
void modify(int l,int r,int v,int t)
{
IT y=s.lower_bound({0,r,0,0});split(y,r);
IT x=s.lower_bound({0,l-1,0,0});split(x,l-1);
x=s.lower_bound({0,l,0,0}),y=s.lower_bound({0,r+1,0,0});
for(IT i=x;i!=y;){
IT j=i;i++;
int ll=j->l,rr=j->r,vv=j->v,tt=j->t;
add(tt,-1*(rr-ll+1)*vv);s.erase(j);
}
s.insert({l,r,v,t}),add(t,(r-l+1)*v);
}
signed main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>n>>m>>qq;
for(int i=1;i<=n;i++)cin>>ql[i]>>qr[i]>>qv[i];
for(int i=1,l,r;i<=qq;i++) cin>>l>>r,que[i]={l,r,i};
sort(que+1,que+qq+1,cmp);
for(int i=1;i<=qq;i++){
for(int j=que[i-1].r+1;j<=que[i].r;j++) {modify(ql[j],qr[j],qv[j],j);}
ans[que[i].id]=query(n)-query(que[i].l-1);
}
for(int i=1;i<=qq;i++) cout<<ans[i]<<'\n';
return 0;
}

浙公网安备 33010602011771号