文章目录
数据结构刷题题单
这是一份来自 p_b_p_b 大佬的题单,但是未完待续啊(我没做完555)。。
题目
CF1132G
- 对于每一个元素,若选择它,那么下一个选择的数是固定的,我们发现这个一个森林的结构,我们在第 n + 1 n+1 n+1的位置上再建一个树根,它就变成了一个树形结构
- 我们先把树建出来,考虑加点删点对答案的影响,每加入一个数,它子树内的所有节点答案加一,每删除一个数,它子树内所有节点答案减一
- 这两个操作在 d f s dfs dfs序上是连续的,于是在 d f s dfs dfs序上用线段树维护,区间加减一,和最大值即可
bzoj4025 二分图
- 一个图是二分图的充要条件是不存在奇环
- 在时间轴上维护线段树,按时间分治,将所有的边插入到被它完全覆盖的线段树节点上
- 用按秩合并的并査集来维护点之间的距离(只记录奇偶),对于每个节点,将其上面所有的边连上,若出现奇环,那么这个区间所有的时刻都不是二分图,回溯那次离开每个节点的时候撤销在这个节点上的所有连边操作
CF848C
- 某个区间内最后一次出现减去第一次出现的条件,给它做一个类似差分的思想,考虑每一个位置 i i i,设 a i a_i ai这个数上次出现的位置是 p r e i pre_i prei,那么区间询问的答案就是 ∑ p r e i ≥ l , i ∈ [ l , r ] i − p r e i \sum_{pre_i \geq l,i \in [l,r]}i-pre_i ∑prei≥l,i∈[l,r]i−prei
- 我们把每个位置的贡献看作一个点 ( i , p r e i ) (i,pre_i) (i,prei),这个点的权值为 i − p r e i i-pre_i i−prei,那么一个 [ l , r ] [l,r] [l,r]的询问就是在求二维平面上 [ l , l ] [l,l] [l,l]到 [ r , r ] [r,r] [r,r]这个矩形的点权和,再算上时间轴那一维,就是三维偏序了,第一维按时间摆好,第二维 x x x轴归并排序,第三维 y y y轴开一个支持单点修改区间查询的树状数组
- 对于每次修改点权变动的点只有旧颜色的前驱后继,新颜色的前驱后继,我们加上新的点把要删除的抵消,把要加入的加上
- 对于每次询问,我们可以把它差分成四个左下角是
[
1
,
1
]
[1,1]
[1,1]的询问,
但是 p b pb pb说不用差分就不用差分!我们发现 p r e i < i pre_i<i prei<i所以我们相当于求矩形 [ 1 , l ] [1,l] [1,l]到 [ r , n ] [r,n] [r,n]的点权和,这就变成两个前缀和相减咯
正睿2019暑假D3T3
- 我们关注一条边,当它关上的那一刻之前,两边的联通块的信息必然相容,这很显然,当它再次打开的时候两边的联通块信息在再次互补,但是上次已经交流过的信息不会产生贡献,那我们设两个联通块这是的信息量分别是 v a l 1 , v a l 2 val_1,val_2 val1,val2,这条边上次关闭前它们的共同信息量是 l a s t last last,那么当这条边再次打开的时候,这整个联通块的信息量会变成 v a l 1 + v a l 2 − l a s t val_1+val_2-last val1+val2−last
- 所以我们并不用维护每个点有的信息具体是些什么,只要维护每个联通块掌握的信息量即可
- 那么我们将这个信息量维护在原树上深度最低的那个点上,然后就可以了
CF576E
- 这是bzoj二分图的加强版,对于多个颜色的情况类似
- 我们处理出每次修改可能维持影响的时间区间,按照这个时间区间将这条边在线段树上插入对应的点
- 每次在线段树上搜到叶子节点时判断yes or no的同时将这条边的颜色确定,和二分图那题一样用按秩合并的并査集维护即可
CF1136E
- 这题的思路就是等价转化一下操作,使得它方便维护
- 令 g i = ∑ j = 1 i k i g_i= \sum_{j=1}^i k_i gi=∑j=1iki,那么 a i ≥ a i − 1 + k i − 1 累 加 得 a i ≥ a 1 + g i − 1 a_i \ge a_{i-1}+ k_{i-1}累加得a_i \ge a_{1}+g_{i-1} ai≥ai−1+ki−1累加得ai≥a1+gi−1
- 再令 u i = a i − g i − 1 , 那 么 由 于 a i ≥ a i − 1 + k i − 1 , 所 以 u i + g i − 1 ≥ u i − 1 + g i − 2 + k i − 1 , 即 u i + g i − 1 ≥ u i − 1 + g i − 1 即 u i ≥ u i − 1 u_i=a_i-g_{i-1},那么由于a_i \ge a_{i-1}+k_{i-1},所以u_i+g_{i-1} \ge u_{i-1}+g_{i-2}+k_{i-1},即u_i+g_{i-1} \ge u_{i-1}+g_{i-1}即u_i\ge u_{i-1} ui=ai−gi−1,那么由于ai≥ai−1+ki−1,所以ui+gi−1≥ui−1+gi−2+ki−1,即ui+gi−1≥ui−1+gi−1即ui≥ui−1,于是就发现操作等价于维护 u i u_{i} ui单调不降
- 那么我们每次修改时只需二分一下需要修改多少个才能使 u i u_i ui不降即可
代码
CF1132G 代码
#include<bits/stdc++.h>
#define FOR(i,a,b) for (register int i=(a);i<=(b);i++)
using namespace std;
const int N=2e6+5;
int n,k,a[N],ans[N],stck[N],top=0;
int tot=0,f[N],nxt[N<<1];
int dfnn=0,dfn[N],siz[N],t[N<<2],tag[N<<2],fa[N];
struct E
{
int u,v;
}e[N<<1];
void Add(int u,int v)
{
tot++;
nxt[tot]=f[u];
f[u]=tot;
e[tot]=(E){u,v};
return;
}
void DFS(int u)
{
dfn[u]=++dfnn;
siz[u]=1;
for(register int j=f[u];j!=-1;j=nxt[j])
{
int v=e[j].v;
if (v==fa[u]) continue;
fa[v]=u;
DFS(v);
siz[u]+=siz[v];
}
return;
}
void push(int p,int l,int r)
{
int mid=(l+r)>>1,ls=p<<1,rs=p<<1|1;
if (!tag[p]) return;
t[ls]+=tag[p];
t[rs]+=tag[p];
tag[ls]+=tag[p];
tag[rs]+=tag[p];
tag[p]=0;
return;
}
void mdf(int p,int l,int r,int L,int R,int val)
{
if (L<=l&&r<=R)
{
t[p]+=val;
tag[p]+=val;
return;
}
int mid=(l+r)>>1,ls=p<<1,rs=p<<1|1;
push(p,l,r);
if (L<=mid) mdf(ls,l,mid,L,R,val);
if (R>mid) mdf(rs,mid+1,r,L,R,val);
t[p]=max(t[ls],t[rs]);
return;
}
int main()
{
memset(f,-1,sizeof(f));
scanf("%d%d",&n,&k);
FOR(i,1,n) scanf("%d",&a[i]);
a[++n]=n+1;
FOR(i,1,n)
{
while (top&&a[stck[top]]<a[i]) Add(stck[top],i),Add(i,stck[top]),top--;
stck[++top]=i;
}
DFS(n);
FOR(i,1,k) mdf(1,1,n,dfn[i],dfn[i]+siz[i]-1,1);
ans[++ans[0]]=t[1];
FOR(i,k+1,n-1)
{
mdf(1,1,n,dfn[i-k],dfn[i-k]+siz[i-k]-1,-1);
mdf(1,1,n,dfn[i],dfn[i]+siz[i]-1,1);
ans[++ans[0]]=t[1];
}
FOR(i,1,ans[0]) printf("%d ",ans[i]);
return 0;
}
bzoj4125二分图 代码
#include<bits/stdc++.h>
#define FOR(i,a,b) for (register int i=(a);i<=(b);i++)
#define pb push_back
using namespace std;
const int N=2e5+5;
int n,m,T,ans[N],fa[N],d[N],dep[N];
struct E
{
int u,v,w;
};
vector <E> G[N<<2];
int read()
{
int x=0,f=1;
char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return f*x;
}
void Insert(int p,int l,int r,int L,int R,int u,int v)
{
if (L<=l&&r<=R)
{
G[p].pb((E){u,v,0});
return;
}
int mid=(l+r)>>1,ls=p<<1,rs=p<<1|1;
if (L<=mid) Insert(ls,l,mid,L,R,u,v);
if (R>mid) Insert(rs,mid+1,r,L,R,u,v);
return;
}
int Getfa(int x)
{
if (fa[x]==x) return x;
else return Getfa(fa[x]);
}
int Getdis(int x)
{
if (fa[x]==x) return 0;
else return d[x]^Getdis(fa[x]);
}
void Del(vector<E> trash)
{
int len=trash.size();
FOR(i,0,len-1)
{
int u=trash[i].u,v=trash[i].v,w=trash[i].w;
fa[u]=u;
d[u]=0;
dep[v]-=w;
}
return;
}
void Solve(int p,int l,int r)
{
vector <E> trash;
trash.clear();
int len=G[p].size();
FOR(i,0,len-1)
{
int u=G[p][i].u,v=G[p][i].v;
int fu=Getfa(u),fv=Getfa(v),dis=Getdis(u)^Getdis(v)^1;
if (fu==fv&&dis)
{
FOR(j,l,r) ans[j]=0;
Del(trash);
return;
}
if (fu!=fv)
{
if (dep[fu]>dep[fv]) swap(fu,fv),swap(u,v);
fa[fu]=fv;
d[fu]=dis;
if (dep[fu]==dep[fv]) dep[fv]++,trash.pb((E){fu,fv,1});
else trash.pb((E){fu,fv,0});
}
}
if (l==r)
{
Del(trash);
ans[l]=1;
return;
}
int mid=(l+r)>>1;
Solve(p<<1,l,mid);
Solve(p<<1|1,mid+1,r);
Del(trash);
return;
}
int main()
{
n=read(),m=read(),T=read();
FOR(i,1,n) fa[i]=i;
FOR(i,1,m)
{
int u=read(),v=read(),st=read()+1,ed=read();
Insert(1,1,T,st,ed,u,v);
}
Solve(1,1,T);
FOR(i,1,T)
if (ans[i]) printf("Yes\n");
else printf("No\n");
return 0;
}
CF848C 代码
#include<bits/stdc++.h>
#define FOR(i,a,b) for (register int i=(a);i<=(b);i++)
#define For(i,a,b) for (register int i=(a);i>=(b);i--)
#define mem(i,j) memset(i,j,sizeof(i))
using namespace std;
typedef long long ll;
const int N=2e6+5;
int n,m,a[N],pos[N],pre[N],tpp=0,opt,tmp1,tmp2;
ll t[N],ans[N];
set <int> s[N];
set <int> :: iterator it;
struct data
{
int x,y,opt;
ll val;
}A[N],B[N];
inline int read()
{
int x=0,f=1;
char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return f*x;
}
inline void Del(int x)
{
it=s[a[x]].find(x);
int pr=0,nx=0;
it++;
if (it!=s[a[x]].end()) nx=*it;
it--;
if (it!=s[a[x]].begin())
{
it--;
pr=*it;
it++;
}
A[++tpp]=(data){x,pr,1,pr-x};
if (nx)
{
A[++tpp]=(data){nx,pre[nx],1,pre[nx]-nx};
pre[nx]=pr;
A[++tpp]=(data){nx,pre[nx],1,nx-pre[nx]};
}
s[a[x]].erase(*it);
return;
}
inline void Insert(int x,int v)
{
a[x]=v;
s[v].insert(x);
it=s[v].find(x);
int nx=0,pr=0;
it++;
if (it!=s[v].end()) nx=*it;
it--;
if (it!=s[v].begin())
{
it--;
pr=*it;
it++;
}
A[++tpp]=(data){x,pr,1,x-pr};
pre[x]=pr;
if (nx)
{
A[++tpp]=(data){nx,pr,1,pr-nx};
pre[nx]=x;
A[++tpp]=(data){nx,x,1,nx-x};
}
return;
}
inline void Input()
{
n=read(),m=read();
FOR(i,1,n)
{
a[i]=read();
s[a[i]].insert(i);
pre[i]=pos[a[i]];
pos[a[i]]=i;
A[++tpp]=(data){i,pre[i],1,i-pre[i]};
}
FOR(i,1,m)
{
opt=read(),tmp1=read(),tmp2=read();
switch (opt)
{
case 1:
Del(tmp1);
Insert(tmp1,tmp2);
break;
case 2:
ans[0]++;
A[++tpp]=(data){tmp1-1,tmp1-1,2,ans[0]};
A[++tpp]=(data){tmp2,tmp2,2,ans[0]};
A[++tpp]=(data){tmp1-1,tmp2,2,-ans[0]};
A[++tpp]=(data){tmp2,tmp1-1,2,-ans[0]};
break;
}
}
return;
}
inline int lowbit(int x)
{
return x&-x;
}
inline void Update(int x,ll v)
{
for (register int i=x;i<=n+1;i+=lowbit(i))
t[i]+=v;
return;
}
inline ll Query(int x)
{
ll ret=0;
for (register int i=x;i;i-=lowbit(i))
ret+=t[i];
return ret;
}
inline void CDQ(int l,int r)
{
if (l==r) return;
int mid=(l+r)>>1;
CDQ(l,mid),CDQ(mid+1,r);
int ql=l,qr=mid+1,tmp=l-1;
while (qr<=r)
{
while (ql<=mid&&A[ql].x<=A[qr].x)
{
if (A[ql].opt==1) Update(A[ql].y,A[ql].val);
B[++tmp]=A[ql++];
}
if (A[qr].opt==2)
{
if (A[qr].val>0) ans[A[qr].val]+=Query(A[qr].y);
else ans[-A[qr].val]-=Query(A[qr].y);
}
B[++tmp]=A[qr++];
}
FOR(i,l,ql-1) if (A[i].opt==1) Update(A[i].y,-A[i].val);
while (ql<=mid) B[++tmp]=A[ql++];
FOR(i,l,r) A[i]=B[i];
// FOR(i,1,n) printf("%d ",t[i]);
// printf("\n");
return;
}
int main()
{
// freopen("data.in","r",stdin);
// freopen("myans.out","w",stdout);
Input();
FOR(i,1,tpp) A[i].x++,A[i].y++;
// FOR(i,1,tpp) printf("%d %d %d %d\n",A[i].x,A[i].y,A[i].opt,A[i].val);
CDQ(1,tpp);
FOR(i,1,ans[0]) printf("%lld\n",ans[i]);
return 0;
}
正睿2019暑假D3T3 代码
#include<bits/stdc++.h>
#define FOR(i,a,b) for (register int i=(a);i<=(b);i++)
using namespace std;
const int N=2e5+5;
int n,m,q,u[N],v[N];
int pre[N],ch[N][2],rev[N];
int query[N],ans[N],val[N],opt[N],now[N],last[N];
//把联通块的信息维护在了原树深度最浅的点的val上
//所以所有破坏树结构的操作(带makeroot) 都要重新调整val的位置
//当然pb大佬教我的不破坏树结构的方法踩了我一百毫秒
int read()
{
int x=0,f=1;
char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return f*x;
}
int nroot(int x) {return ch[pre[x]][0]==x||ch[pre[x]][1]==x;}
void Update_rev(int p) {if (!p) return;swap(ch[p][0],ch[p][1]);rev[p]^=1;return;}
void Push(int p) {if (!rev[p]) return;if (!rev[p]) return;Update_rev(ch[p][0]);Update_rev(ch[p][1]);rev[p]=0;return;}
void Rotate(int x)
{
int y=pre[x],k=(ch[y][0]==x);
ch[y][!k]=ch[x][k];
if (ch[x][k]) pre[ch[x][k]]=y;
if (pre[y]&&nroot(y)) ch[pre[y]][(ch[pre[y]][1]==y)]=x;
pre[x]=pre[y];
pre[y]=x;
ch[x][k]=y;
return;
}
void Pushall(int x)
{
if (nroot(x)) Pushall(pre[x]);
Push(x);
return;
}
void Splay(int x)
{
Pushall(x);
while (nroot(x))
{
int y=pre[x],z=pre[y];
if (nroot(y))
{
if ((ch[z][1]==y)xor(ch[y][1]==x)) Rotate(x);
else Rotate(y);
}
Rotate(x);
}
return;
}
void Access(int x)
{
int y=0;
for (;x;x=pre[y=x])
{
Splay(x);
ch[x][1]=y;
}
return;
}
int Getrt(int x)
{
Access(x);
Splay(x);
while (ch[x][0]) x=ch[x][0];
Splay(x);
return x;
}
void Make_root(int x)
{
int tmpval=val[Getrt(x)];
Access(x);
Splay(x);
Update_rev(x);
val[x]=tmpval;
return;
}
void Link(int u,int v)
{
Make_root(u);
pre[u]=v;
return;
}
void Cut(int u,int v)
{
int tmpval=val[Getrt(u)];
Make_root(u);
Access(v);
Splay(v);
pre[u]=ch[v][0]=0;
val[Getrt(u)]=val[Getrt(v)]=tmpval;
return;
}
int main()
{
n=read(),m=read(),q=read();
FOR(i,1,n-1) u[i]=read(),v[i]=read();
FOR(i,1,m) opt[i]=read();
FOR(i,1,q) query[i]=read();
FOR(i,1,n) val[i]=1;
FOR(i,1,m)
{
if (!now[opt[i]])
{
int v1=val[Getrt(u[opt[i]])],v2=val[Getrt(v[opt[i]])];
Link(u[opt[i]],v[opt[i]]);
val[Getrt(u[opt[i]])]=v1+v2-last[opt[i]];
}
else
{
last[opt[i]]=val[Getrt(u[opt[i]])];
Cut(u[opt[i]],v[opt[i]]);
}
now[opt[i]]^=1;
}
FOR(i,1,q) ans[i]=val[Getrt(query[i])];
FOR(i,1,q) printf("%d\n",ans[i]);
return 0;
}
CF576E 代码
#include<bits/stdc++.h>
#define FOR(i,a,b) for (register int i=(a);i<=(b);i++)
#define For(i,a,b) for (register int i=(a);i>=(b);i--)
#define GO(u) for (register int j=f[u];j!=-1;j=nxt[j])
#define mem(i,j) memset(i,j,sizeof(i))
#define MP make_pair
#define pb push_back
#define fi first
#define se second
using namespace std;
const int N=5e5+5;
const int K=55;
int n,m,k,q,tmp1,tmp2,in1[N],in2[N],last[N],ll[N],rr[N],ans[N];
int fa[K][N],dep[K][N],dis[K][N];
vector <int> vec[N<<2];
struct data
{
int u,v,col,w;
}e[N];
inline int read()
{
int x=0,f=1;
char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return f*x;
}
inline void write(int x)
{
if (x<0) putchar('-'),x=-x;
if (x>9) write(x/10);
putchar(x%10+'0');
return;
}
inline int getfa(int col,int x) {return (fa[col][x]==x)?x:getfa(col,fa[col][x]);}
inline int getdis(int col,int x) {return (fa[col][x]==x)?0:(getdis(col,fa[col][x]) xor dis[col][x]);}
inline relation(int col,int u,int v)
{
int fu=getfa(col,u),fv=getfa(col,v);
return (fu==fv);
}
inline data merge(int col,int u,int v)
{
int fu=getfa(col,u),fv=getfa(col,v);
data ret=(data){fu,fv,col,0};
if (dep[col][fu]>dep[col][fv]) swap(u,v),swap(fu,fv),swap(ret.u,ret.v);
int tmp_dis=getdis(col,u) xor getdis(col,v) xor 1;
dis[col][fu]=tmp_dis;
fa[col][fu]=fv;
if (dep[col][fu]==dep[col][fv]) dep[col][fv]++,ret.w=1;
return ret;
}
inline void del(stack <data> stck)
{
while (stck.size())
{
data tmp=stck.top();
stck.pop();
int fu=tmp.u,fv=tmp.v,col=tmp.col,w=tmp.w;
dep[col][fv]-=w;
fa[col][fu]=fu;
dis[col][fu]=0;
}
return;
}
inline void insert(int p,int l,int r,int L,int R,int num)
{
if (L<=l&&r<=R)
{
vec[p].pb(num);
return;
}
int mid=(l+r)>>1,ls=p<<1,rs=p<<1|1;
if (L<=mid) insert(ls,l,mid,L,R,num);
if (R>mid) insert(rs,mid+1,r,L,R,num);
return;
}
inline void solve(int p,int l,int r)
{
stack <data> stck;
while (stck.size()) stck.pop();
if (l>r) return;
FOR(i,0,(int)vec[p].size()-1)
{
data tmp_e=e[vec[p][i]];
int u=tmp_e.u,v=tmp_e.v,col=tmp_e.col;
if (!col) continue;
if (relation(col,u,v)) continue;
stck.push(merge(col,u,v));
}
if (l==r)
{
data tmp_e=e[in1[l]];
int judge1=getdis(in2[l],tmp_e.u) xor getdis(in2[l],tmp_e.v) xor 1;
int judge2=relation(in2[l],tmp_e.u,tmp_e.v);
if (judge1&&judge2) ans[l]=0;
else
{
e[in1[l]].col=in2[l];
ans[l]=1;
}
del(stck);
return;
}
int mid=(l+r)>>1,ls=p<<1,rs=p<<1|1;
solve(ls,l,mid);
solve(rs,mid+1,r);
del(stck);
return;
}
int main()
{
// freopen("data.in","r",stdin);
n=read(),m=read(),k=read(),q=read();
FOR(i,1,m) tmp1=read(),tmp2=read(),e[i]=(data){tmp1,tmp2,0,0};
FOR(i,1,q)
{
tmp1=read(),tmp2=read();
in1[i]=tmp1,in2[i]=tmp2;
if (last[tmp1]) rr[last[tmp1]]=i-1;
last[tmp1]=i;
ll[i]=i+1;
rr[i]=q;
}
FOR(i,1,k) FOR(j,1,n) fa[i][j]=j;
FOR(i,1,q) if (ll[i]<=rr[i]) insert(1,1,q,ll[i],rr[i],in1[i]);
solve(1,1,q);
FOR(i,1,q)
{
if (ans[i]) printf("YES\n");
else printf("NO\n");
}
return 0;
}
CF1136E 代码
#include<bits/stdc++.h>
#define FOR(i,a,b) for (register ll i=(a);i<=(b);i++)
#define For(i,a,b) for (register ll i=(a);i>=(b);i--)
#define mem(i,j) memset(i,j,sizeof(i))
#define GO(u) for (register ll j=f[u];j!=-1;j=nxt[j])
using namespace std;
typedef long long ll;
const ll N=4e5+5;
ll n,a[N],k[N],q,tmp1,tmp2,ans[N],pos,tmp;
ll g[N],f[N];
char s[2];
ll t[N<<2],tag[N<<2],sum[N<<2],vis[N];
inline ll read()
{
ll x=0,f=1;
char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return f*x;
}
inline void write(ll x)
{
if (x<0) putchar('-'),x=-x;
if (x>9) write(x/10);
putchar(x%10+'0');
return;
}
inline void bd(ll p,ll l,ll r)
{
tag[p]=0;
vis[p]=0;
if (l==r)
{
t[p]=a[l]-g[l-1];
sum[p]=t[p];
return;
}
ll mid=(l+r)>>1,ls=p<<1,rs=p<<1|1;
bd(ls,l,mid);
bd(rs,mid+1,r);
sum[p]=sum[ls]+sum[rs];
return;
}
inline void down(ll p,ll l,ll r)
{
if (!vis[p]) return;
ll mid=(l+r)>>1,ls=p<<1,rs=p<<1|1;
tag[ls]=tag[p];
tag[rs]=tag[p];
t[ls]=t[rs]=tag[p];
sum[ls]=(mid-l+1)*tag[p];
sum[rs]=(r-mid)*tag[p];
vis[ls]=vis[rs]=1;
vis[p]=0;
tag[p]=0;
return;
}
inline ll query(ll p,ll l,ll r,ll L,ll R)
{
if (L<=l&&r<=R) return sum[p];
ll mid=(l+r)>>1,ls=p<<1,rs=p<<1|1,ret=0;
down(p,l,r);
if (L<=mid) ret+=query(ls,l,mid,L,R);
if (R>mid) ret+=query(rs,mid+1,r,L,R);
sum[p]=sum[ls]+sum[rs];
return ret;
}
inline void md(ll p,ll l,ll r,ll L,ll R,ll v)
{
if (L<=l&&r<=R)
{
vis[p]=1;
tag[p]=v;
t[p]=v;
sum[p]=(r-l+1)*v;
return;
}
ll mid=(l+r)>>1,ls=p<<1,rs=p<<1|1;
down(p,l,r);
if (L<=mid) md(ls,l,mid,L,R,v);
if (R>mid) md(rs,mid+1,r,L,R,v);
sum[p]=sum[ls]+sum[rs];
return;
}
inline ll find(ll l,ll val)
{
ll L=l,R=n,MID;
while (L<R)
{
MID=(L+R+1)>>1;
if (query(1,1,n,MID,MID)>val) R=MID-1;
else L=MID;
}
return L;
}
int main()
{
// freopen("data.in","r",stdin);
n=read();
FOR(i,1,n) a[i]=read();
FOR(i,1,n-1) k[i]=read();
FOR(i,1,n-1) g[i]=g[i-1]+k[i];
FOR(i,1,n-1) f[i]=f[i-1]+g[i];
q=read();
bd(1,1,n);
while (q--)
{
scanf("%s",s+1);
tmp1=read(),tmp2=read();
switch (s[1])
{
case 's':
ans[++ans[0]]=query(1,1,n,tmp1,tmp2)+f[tmp2-1]-f[tmp1-2];
break;
case '+':
tmp=query(1,1,n,tmp1,tmp1);
tmp+=tmp2;
pos=find(tmp1,tmp);
md(1,1,n,tmp1,pos,tmp);
break;
}
}
FOR(i,1,ans[0]) write(ans[i]),putchar('\n');
return 0;
}