1 条题解
-
0
线段树具有很优秀的性质并且易于扩展。例如,对于懒标记的下传操作,我们可以使用标记永久化取消。而这道题则对上传操作进行了扩展,利用了线段树树高只有 层的性质,对区间贡献的情况进行了分类讨论(实质为在线段树这一结构上二分)来统计贡献。
天数区间很大,于是我们考虑维护下标区间 的动态开点线段树。思考我们要维护哪些信息。
- 显然,我们要维护答案区间 。
- 对于一个区间,我们需要知道其对之后区间的干草捆数贡献 。
- 为了在合并时知道贡献,我们需要维护当前区间有多少天还未有干草。由于区间范围过大,我们转而维护当前区间有干草吃的天数 。
- 知道了左区间对之后区间干草捆数贡献,如何查找左区间当前左区间对右区间的贡献 ?我们另开一个函数求解此信息,函数作用为:求解区间 在左边有 捆干草送入(且自身已有一定的贡献)的情况下会对答案数组有多少贡献。
考虑实现该函数,我们利用 数组进行判断:
- 如果 会在 内消耗完,那么就对 没有影响,求解 在 之内的贡献,再加上右区间内部的贡献。发现右区间内部贡献就是右儿子的 ,因此右区间的查询是 的。
- 否则说明 中每一天都有干草吃,对其 计算,将 减去左区间没有干草吃的天数,对右区间进行求解。
上面两种情况都只会对一个儿子向下求解,因此其复杂度为 。所以总复杂度为 ,可以通过此题。
#include<bits/stdc++.h> #define endl '\n' #define ll long long #define pre(i,a,b) for(int i=a;i<=b;++i) using namespace std; ll read(ll t = 0, bool f = 1, char c = 0) { while(!isdigit(c = getchar())) f = c^45; while(isdigit(c)) t = (t << 1) + (t << 3) + (c ^ 48), c = getchar(); return f ? t: -t; } const int N=1e7+5,p=1e9+7,i2=500000004; int tot, rt=1; #define mid ((l+r)>>1) array<int,N> ls,rs; array<ll,N> ans,num,rem,nop; int plu(int u,int v) { return u+v>=p?u+v-p:u+v; } int mul(int u,int v) { return (1ll*u*v)%p; } int sum(ll n) { return mul(mul(n%p,(n+1)%p),i2); } int range(ll l,ll r) { assert(l<=r);return plu(sum(r),p-sum(l-1)); } int query(int u,ll l,ll r,ll x) { if(l==r) return x?l%p:ans[u]; if(mid-l+1-num[ls[u]]>=x) return plu(query(ls[u],l,mid,x),nop[u]); else return plu(range(l,mid),query(rs[u],mid+1,r,x-(mid-l+1-num[ls[u]])+rem[ls[u]])); } void pu(int u,ll l,ll r) { num[u]=num[ls[u]]+min(num[rs[u]]+rem[ls[u]],r-mid); rem[u]=rem[rs[u]]+max(num[rs[u]]+rem[ls[u]]-(r-mid),0ll); ans[u]=plu(ans[ls[u]],(nop[u]=query(rs[u],mid+1,r,rem[ls[u]]))); } void add(ll f,ll val,int &u=rt,ll l=1,ll r=2e14) { if(u==0) u=++tot; if(l==r) { if(val==0) ans[u]=rem[u]=num[u]=0; else ans[u]=l%p,num[u]=1,rem[u]=val-1; return; } if(f<=mid) add(f,val,ls[u],l,mid); else add(f,val,rs[u],mid+1,r); pu(u,l,r); } void B() { ll q=read(),d,b;; tot=1; while(q--) { d=read(),b=read(); add(d,b); printf("%lld\n",ans[rt]); } } signed main() { int T;T=1;B(); return 0; }
- 1
信息
- ID
- 7677
- 时间
- 6000ms
- 内存
- 512MiB
- 难度
- 8
- 标签
- 递交数
- 21
- 已通过
- 6
- 上传者