Description
给出一个长度为 nn 的数列 A,接下来有 m 次操作,操作有三种:
对于所有的 i∈[l,r],将 Ai 变成 Ai+x。
对于所有的 i∈[l,r],将 Ai 变成 ⌊√Ai⌋。
对于所有的 i∈[l,r],询问 Ai 的和。
n,m,Ai,x<=10^5
小清新线段树
感性上看,值相同的一段会越来越长
如果整个区间开根下整全部相等,我就可以相当成一个区间覆盖操作
这样仍然会T
反例就是3 4,你开了根,变成1 2,再加2,不断重复,就卡成n^2了
如果整个区间开根下整,原值与新值差一定,那么相当于一个区间减的操作
这样就不会被卡了
复杂度不会证QAQ,据说是
nlognloglogn
的
Code
代码丑
void putag(node &v,ll n,ll mul,ll add)
{
v.sm=v.sm*mul+n*add,v.mx=v.mx*mul+add,v.mn=v.mn*mul+add;
v.mul*=mul,v.add=mul*v.add+add;
}
void modify(int v,int l,int r,int x,int y)
{
if(y<l || x>r) return;
if(x<=l && r<=y && tr[v].mx-tr[v].mn<=1)
{
ll tx=sqrt(tr[v].mx),ty=sqrt(tr[v].mn);
if(tx==ty) putag(tr[v],r-l+1,0,tx);
else putag(tr[v],r-l+1,1,-(tr[v].mx-tx));
return;
}
down(v,l,r);
int mid=(l+r)>>1;
modify(v+v,l,mid,x,y);modify(v+v+1,mid+1,r,x,y);
update(v);
}