1. 程式人生 > >【UOJ #228】 基礎資料結構練習題

【UOJ #228】 基礎資料結構練習題

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,據說是n

lognloglogn

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); }