P8512 [Ynoi Easy Round 2021] TEST_152 题解
前置知识
珂朵莉树/颜色段均摊 | 树状数组 | 扫描线
解法
同 luogu P5524 [Ynoi2012] NOIP2015 充满了希望,询问时扫描线维护,树状数组维护时间戳(单点修改区间查询)即可。前者具体部分看我 luogu P5524 [Ynoi2012] NOIP2015 充满了希望 题解 吧。
区间推平考虑珂朵莉树,推平时类似 CF915E Physical Education Lessons | CF1638E Colorful Operations 维护下全局和即可。
感觉有点纯珂朵莉树板子了。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define sort stable_sort
#define endl '\n'
ll l[500010],r[500010],val[500010],ans[500010];
vector<pair<ll,ll> >e[500010];
struct BIT
{
ll c[500010];
ll lowbit(ll x)
{
return (x&(-x));
}
void add(ll n,ll x,ll val)
{
if(x!=0)
{
for(ll i=x;i<=n;i+=lowbit(i))
{
c[i]+=val;
}
}
}
ll getsum(ll x)
{
ll ans=0;
for(ll i=x;i>=1;i-=lowbit(i))
{
ans+=c[i];
}
return ans;
}
}B;
struct ODT
{
struct node
{
ll l,r;
mutable ll col,t;
bool operator < (const node &another) const
{
return l<another.l;
}
};
set<node>s;
void init(ll n)
{
s.insert((node){1,n,0,0});
}
set<node>::iterator split(ll pos)
{
set<node>::iterator it=s.lower_bound((node){pos,0,0,0});
if(it!=s.end()&&it->l==pos)
{
return it;
}
it--;
if(it->r<pos)
{
return s.end();
}
ll l=it->l,r=it->r,col=it->col,t=it->t;
s.erase(it);
s.insert((node){l,pos-1,col,t});
return s.insert((node){pos,r,col,t}).first;
}
void assign(ll l,ll r,ll col,ll n,ll t)
{
set<node>::iterator itr=split(r+1),itl=split(l);
for(set<node>::iterator it=itl;it!=itr;it++)
{
B.add(n,it->t,-(it->col*(it->r-it->l+1)));
}
s.erase(itl,itr);
s.insert((node){l,r,col,t});
B.add(n,t,col*(r-l+1));
}
}O;
int main()
{
ll n,m,q,x,y,i,j;
cin>>n>>m>>q;
O.init(m);
for(i=1;i<=n;i++)
{
cin>>l[i]>>r[i]>>val[i];
}
for(i=1;i<=q;i++)
{
cin>>x>>y;
e[y].push_back(make_pair(x,i));
}
for(i=1;i<=n;i++)
{
O.assign(l[i],r[i],val[i],n,i);
for(j=0;j<e[i].size();j++)
{
ans[e[i][j].second]=B.getsum(i)-B.getsum(e[i][j].first-1);
}
}
for(i=1;i<=q;i++)
{
cout<<ans[i]<<endl;
}
return 0;
}
本文来自博客园,作者:hzoi_Shadow,原文链接:https://www.cnblogs.com/The-Shadow-Dragon/p/18366136,未经允许严禁转载。
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。