<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      「BZOJ 4765」普通計算姬 題解

      「BZOJ 4765」普通計算姬 題解


      知識點

      主席樹,分塊,DFS 序。

      分析

      \(O(m\sqrt{n\log_2{n}})\)

      我們可以離線對修改操作分塊,假設每塊長度為 \(B\)

      那么對于每塊有修改的點存下來,其余的點 \(O(n)\) 的復雜度內預處理出來,以前綴和的方式存下來。

      那么我們發現每個有修改的點對于區間 \([l,r]\) 的貢獻個數就等于在 \([l,r]\) 內有幾個是它的祖先,這部分主席樹即可。

      那么我們復雜度為 \(O(\frac{m}{B}n+mB\log_2{n})\),在 \(B=\sqrt{\frac{n}{\log_2{n}}}\) 時取到最小值 \(O(m\sqrt{n\log_2{n}})\)

      時間復雜度 \(O(m\sqrt{n\log_2{n}})\),空間復雜度 \(O(n\log_2{n})\)。

      提示

      在每塊預處理的時候,可以先處理出按 DFS 序排序的序列,這樣會快很多。

      \(O(m\sqrt{n})\)

      我們對序列分塊。

      • 考慮查詢,我們會有整塊和散點。

        對于整塊,我們直接查詢;對于散點,我們可以考慮用數據結構維護 DFS 序子樹和。

      • 考慮修改,對應上面的整塊和散點。

        整塊的部分,我們預處理出每個點在每一塊有幾個祖先;散點直接在數據結構上修改即可。

      那么數據結構選用分塊用來平衡,這里的分塊是修改 \(O(\sqrt{n})\),查詢 \(O(1)\) 的。

      總時間復雜度 \(O(m\sqrt{n})\),空間復雜度 \(O(n\sqrt{n})\)。

      提示

      記「每個點在每一塊有幾個祖先」時,可以將數組開成 short,會快很多。

      代碼

      \(O(m\sqrt{n\log_2{n}})\)

      //#define Plus_Cat "common"
      #include<bits/stdc++.h>
      #define INF 0x3f3f3f3f
      #define ll long long
      #define uint unsigned int
      #define ull unsigned long long
      #define RCL(a,b,c,d) memset(a,b,sizeof(c)*(d))
      #define FOR(i,a,b) for(int i(a);i<=(int)(b);++i)
      #define DOR(i,a,b) for(int i(a);i>=(int)(b);--i)
      #define tomax(a,...) ((a)=max({(a),__VA_ARGS__}))
      #define tomin(a,...) ((a)=min({(a),__VA_ARGS__}))
      #define EDGE(g,i,x,y) for(int i=(g).h[(x)],y=(g)[(i)].v;~i;y=(g)[(i=(g)[i].nxt)>0?i:0].v)
      #define main Main();signed main(){ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);return Main();}signed Main
      using namespace std;
      constexpr int N(1e5+10);
      
      namespace IOEcat {
      	//Fast IO...
      } using namespace IOEcat;
      
      bool vis[N];
      int n,m,rt,Bl,Bn,cha,que,idx;
      int a[N],fa[N],dfn[N];
      ull ans[N],sum[N],Sum[N];
      struct CFS {
      	int tot,h[N];
      	struct edge {
      		int v,nxt;
      		edge(int v=0,int nxt=-1):v(v),nxt(nxt) {}
      	} e[N<<1];
      
      	CFS():tot(0) {}
      
      	edge &operator [](int i) { return e[i]; }
      
      	void Init(int n) { RCL(h+1,-1,int,n),tot=-1; }
      
      	void att(int u,int v) { e[++tot]=edge(v,h[u]),h[u]=tot; }
      
      	void con(int u,int v) { att(u,v),att(v,u); }
      } g;
      struct Change { int u,d; } Cha[N];
      struct Query { int t,l,r; } Que[N];
      struct SEG {
      	int tot;
      	int rt[N];
      	struct node { int ls,rs,sum; } tr[N*18];
      
      	int &operator [](int i) { return rt[i]; }
      #define ls(p) (tr[p].ls)
      #define rs(p) (tr[p].rs)
      #define mid ((l+r)>>1)
      	void Plus(int x,int &p,int q,int l=1,int r=n) {
      		tr[p=++tot]=tr[q],++tr[p].sum;
      		if(l==r)return;
      		return x<=mid?Plus(x,ls(p),ls(q),l,mid):Plus(x,rs(p),rs(q),mid+1,r);
      	}
      
      	int Sum(int L,int R,int p,int l=1,int r=n) {
      		if(L<=l&&r<=R)return tr[p].sum;
      		if(R<=mid)return Sum(L,R,ls(p),l,mid);
      		if(mid<L)return Sum(L,R,rs(p),mid+1,r);
      		return Sum(L,R,ls(p),l,mid)+Sum(L,R,rs(p),mid+1,r);
      	}
      #undef ls
      #undef rs
      #undef mid
      } seg;
      
      void dfs(int u) {
      	seg.Plus(u,seg[u],seg[fa[u]]),sum[u]=a[u],dfn[++idx]=u;
      	EDGE(g,i,u,v)if(v^fa[u])fa[v]=u,dfs(v),sum[u]+=sum[v];
      }
      
      signed main() {
      #ifdef Plus_Cat
      	freopen(Plus_Cat ".in","r",stdin),freopen(Plus_Cat ".out","w",stdout);
      #endif
      	/*DE("Input & Build");*/
      	I(n,m),g.Init(n);
      	FOR(i,1,n)I(a[i]);
      	FOR(i,1,n) {
      		int u,v;
      		I(u,v);
      		if(u>v)swap(u,v);
      		u?g.con(u,v),0:rt=v;
      	}
      	dfs(rt);
      	/*DE("Offline");*/
      	FOR(i,1,m) {
      		int op,x,y;
      		I(op,x,y),op==1?(Cha[++cha]= {x,y},0):(Que[++que]= {cha,x,y},0);
      	}
      	DE(cha,que);
      	/*DE("Solve");*/
      	Bl=max(1,(int)ceil(sqrt(1.0*cha/log2(3.0*max(2,cha))))),Bn=(cha-1)/Bl+1;
      	int it(1);
      	FOR(j,1,n)Sum[j]=Sum[j-1]+sum[j];
      	while(it<=que&&Que[it].t<=0)ans[it]=(Sum[Que[it].r]-Sum[Que[it].l-1]),++it;
      	FOR(i,1,Bn) {
      		const int l((i-1)*Bl+1),r(min(cha,i*Bl));
      		vector<int> tmp;
      		FOR(j,l,r)if(!vis[Cha[j].u])vis[Cha[j].u]=1,tmp.push_back(Cha[j].u);
      		FOR(j,1,n)sum[j]=(vis[j]?0:a[j]);
      		DOR(j,n,1)sum[fa[dfn[j]]]+=sum[dfn[j]];
      		FOR(j,1,n)Sum[j]=Sum[j-1]+sum[j];
      		FOR(j,l,r) {
      			a[Cha[j].u]=Cha[j].d;
      			while(it<=que&&Que[it].t<=j) {
      				ans[it]=(Sum[Que[it].r]-Sum[Que[it].l-1]);
      				for(int u:tmp)ans[it]+=(ull)a[u]*seg.Sum(Que[it].l,Que[it].r,seg[u]);
      				++it;
      			}
      		}
      		FOR(j,l,r)if(vis[Cha[j].u])vis[Cha[j].u]=0;
      	}
      	/*DE("Output");*/
      	FOR(i,1,que)O(ans[i],'\n');
      	return 0;
      }
      

      \(O(m\sqrt{n})\)

      //#define Plus_Cat "common"
      #include<bits/stdc++.h>
      #define INF 0x3f3f3f3f
      #define ll long long
      #define uint unsigned int
      #define ull unsigned long long
      #define RCL(a,b,c,d) memset(a,b,sizeof(c)*(d))
      #define FOR(i,a,b) for(int i(a);i<=(int)(b);++i)
      #define DOR(i,a,b) for(int i(a);i>=(int)(b);--i)
      #define tomax(a,...) ((a)=max({(a),__VA_ARGS__}))
      #define tomin(a,...) ((a)=min({(a),__VA_ARGS__}))
      #define EDGE(g,i,x,y) for(int i=(g).h[(x)],y=(g)[(i)].v;~i;y=(g)[(i=(g)[i].nxt)>0?i:0].v)
      #define main Main();signed main(){ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);return Main();}signed Main
      using namespace std;
      constexpr int N(1e5+10),sN(317+10);
      
      namespace IOEcat {
      	//Fast IO...
      } using namespace IOEcat;
      
      int n,m,rt,idx;
      int a[N],fa[N],dl[N],dr[N],dfn[N];
      struct CFS {
      	int tot,h[N];
      	struct edge {
      		int v,nxt;
      		edge(int v=0,int nxt=-1):v(v),nxt(nxt) {}
      	} e[N<<1];
      
      	CFS():tot(0) {}
      
      	edge &operator [](int i) { return e[i]; }
      
      	void Init(int n) { RCL(h+1,-1,int,n),tot=-1; }
      
      	void att(int u,int v) { e[++tot]=edge(v,h[u]),h[u]=tot; }
      
      	void con(int u,int v) { att(u,v),att(v,u); }
      } g;
      
      namespace Block {
      	short cnt[N][sN];
      	int Bl,Bn;
      	int st[sN],en[sN],bel[N];
      	ull sum[sN];
      	struct block {
      		ull pre[N],Pre[sN];
      
      		void Build(const int Bn) {
      			FOR(i,1,Bn) {
      				FOR(j,st[i],en[i])pre[j]=(j>st[i]?pre[j-1]:0)+a[dfn[j]];
      				Pre[i]=Pre[i-1]+pre[en[i]];
      			}
      		}
      
      		void Plus(int x,int d) {
      			FOR(i,x,en[bel[x]])pre[i]+=d;
      			FOR(i,bel[x],Bn)Pre[i]+=d;
      		}
      
      		ull Sum(int x) { return Pre[bel[x]-1]+pre[x]; }
      
      		ull Sum(int l,int r) { return Sum(r)-Sum(l-1); }
      	} blo;
      
      	void Build(const int n) {
      		Bl=ceil(sqrt(n)),Bn=(n-1)/Bl+1;
      		FOR(i,1,Bn) {
      			st[i]=en[i-1]+1,en[i]=min(en[i-1]+Bl,n);
      			FOR(j,st[i],en[i])bel[j]=i;
      		}
      	}
      } using namespace Block;
      
      ull dfs(int u) {
      	ull Sum(a[u]);
      	FOR(i,1,Bn)cnt[u][i]=cnt[fa[u]][i];
      	dfn[dl[u]=++idx]=u,++cnt[u][bel[u]];
      	EDGE(g,i,u,v)if(v^fa[u])fa[v]=u,Sum+=dfs(v);
      	return dr[u]=idx,sum[bel[u]]+=Sum,Sum;
      }
      
      signed main() {
      #ifdef Plus_Cat
      	freopen(Plus_Cat ".in","r",stdin),freopen(Plus_Cat ".out","w",stdout);
      #endif
      	/*DE("Input & Build");*/
      	I(n,m),g.Init(n);
      	FOR(i,1,n)I(a[i]);
      	FOR(i,1,n) {
      		int u,v;
      		I(u,v);
      		if(u>v)swap(u,v);
      		u?g.con(u,v),0:rt=v;
      	}
      	Build(n),dfs(rt),blo.Build(Bn);
      	while(m--) {
      		int op;
      		I(op);
      		if(op==1) {
      			int u,d;
      			I(u,d),blo.Plus(dl[u],d-a[u]);
      			FOR(i,1,Bn)sum[i]+=(ull)(d-a[u])*cnt[u][i];
      			a[u]=d;
      		} else {
      			int l,r,bl,br;
      			ull ans(0);
      			I(l,r),bl=bel[l],br=bel[r];
      			if(bl==br) {
      				FOR(i,l,r)ans+=blo.Sum(dl[i],dr[i]);
      				O(ans,'\n');
      				continue;
      			}
      			FOR(i,l,en[bl])ans+=blo.Sum(dl[i],dr[i]);
      			FOR(i,st[br],r)ans+=blo.Sum(dl[i],dr[i]);
      			FOR(i,bl+1,br-1)ans+=sum[i];
      			O(ans,'\n');
      		}
      	}
      	return 0;
      }
      

      posted @ 2025-06-07 11:01  Add_Catalyst  閱讀(12)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 网友偷拍视频一区二区三区| 国产人妻人伦精品婷婷| 亚洲欧美综合精品成| av午夜福利一片免费看久久| 成人3d动漫一区二区三区| 久久久久久综合网天天| 国产亚洲真人做受在线观看| 国产精品十八禁在线观看| 少妇又紧又色又爽又刺激视频| 国内精品久久人妻无码不卡| 国产免费午夜福利在线播放| 欧洲中文字幕国产精品| 在线日韩日本国产亚洲| 无码人妻一区二区三区AV| 亚洲码国产精品高潮在线| 欧乱色国产精品兔费视频 | 成人亚欧欧美激情在线观看| 久久热99这里只有精品| 国产精品店无码一区二区三区| 长治县| 深夜福利成人免费在线观看 | 久久人人妻人人爽人人爽| 亚洲成av人最新无码不卡短片| 国产亚洲精品成人aa片新蒲金| 无码免费大香伊蕉在人线国产| 日本亚洲欧洲免费无线码| 国产精品成人午夜久久| 中国孕妇变态孕交xxxx| 国内精品人妻无码久久久影院导航 | 青青狠狠噜天天噜日日噜| 国产资源精品中文字幕| 国产亚洲精久久久久久无码77777| 免费无码va一区二区三区| 日韩幕无线码一区中文| 绥化市| 国产精品美女一区二区三| 亚洲AV色香蕉一区二区蜜桃小说| 中国老熟女重囗味hdxx| 蜜臀精品视频一区二区三区 | 国产999久久高清免费观看| 国产精品区一区第一页|