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

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

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

      【題解】Luogu P7394 「TOCO Round 1」History

      看到“回到 \(x\) 后的狀態”,顯然考慮可持久化線段樹。記開燈的為 \(1\),關燈的為 \(0\),對于每個詢問只需去查某些點的權值和即可。

      考慮怎么將符合條件的點轉化為區間。詢問的是同一深度的點,可以考慮 bfs 序。考慮如果 \(y\) 是奇數,顯然答案為 \(0\);否則詢問的點就是 \(x\)\(\frac{y}{2}\) 級祖先在 \(x\) 這一層的后代,再去掉 \(x\)\(\frac{y}{2}-1\) 級祖先在 \(x\) 這一層的后代。考慮怎么去找到詢問對應的區間。對于同一棵子樹的同一深度,其 bfs 序是連續的。因此可以將詢問先存下來,對于每個節點建線段樹,存儲某一深度的 bfs 序最大值和最小值。線段樹合并即可。

      時間復雜度分析,處理操作時每次都為 \(O(\log n)\),所有線段樹合并的總時間復雜度為 \(O(n\log n)\),于是總的時間復雜度就為 \(O((n+m)\log n)\)

      #include<bits/stdc++.h>
      #define ll long long
      #define il inline
      #define pb push_back
      #define pii pair<int,int>
      #define mp make_pair
      #define fir first
      #define sec second
      using namespace std;
      namespace asbt{
      namespace cplx{bool begin;}
      const int maxn=1e5+5;
      const int inf=0x3f3f3f3f;
      int n,m,dep[maxn];
      int anc[maxn][22];
      int bfn[maxn];
      queue<int> q;
      vector<int> e[maxn];
      vector<pii> quj[maxn];
      struct{
      	int opt,x,y;
      	int l1,r1,l2,r2;
      }wt[maxn];
      il void dfs1(int u,int fa){
      	dep[u]=dep[fa]+1;
      	anc[u][0]=fa;
      	for(int i=1;i<=20;i++){
      		anc[u][i]=anc[anc[u][i-1]][i-1];
      	}
      	for(int v:e[u]){
      		if(v==fa){
      			continue;
      		}
      		dfs1(v,u);
      	}
      }
      il int ganc(int u,int k){
      	int tmp=0;
      	while(k){
      		if(k&1){
      			u=anc[u][tmp];
      		}
      		k>>=1,tmp++;
      	}
      	return u;
      }
      il void bfs(){
      	int cnt=0;
      	q.push(1);
      	while(q.size()){
      		int u=q.front();
      		q.pop(),bfn[u]=++cnt;
      		for(int v:e[u]){
      			if(!bfn[v]){
      				q.push(v);
      			}
      		}
      	}
      }
      int rt[maxn],tot,ls[maxn*40],rs[maxn*40],sum[maxn*40],mn[maxn*40],mx[maxn*40];
      il int New(){
      	tot++;
      	ls[tot]=rs[tot]=sum[tot];
      	mn[tot]=inf,mx[tot]=-inf;
      	return tot;
      }
      il void pushup(int id){
      	sum[id]=sum[ls[id]]+sum[rs[id]];
      }
      il void build(int &id,int l,int r){
      	id=New();
      	if(l==r){
      		return ;
      	}
      	int mid=(l+r)>>1;
      	build(ls[id],l,mid);
      	build(rs[id],mid+1,r);
      }
      il void add(int &id,int l,int r,int p,int v){
      	if(!id){
      		id=New();
      	}
      	if(l==r){
      		mn[id]=min(mn[id],v);
      		mx[id]=max(mx[id],v);
      		return ;
      	}
      	int mid=(l+r)>>1;
      	if(p<=mid){
      		add(ls[id],l,mid,p,v);
      	}
      	else{
      		add(rs[id],mid+1,r,p,v);
      	}
      	mn[id]=min(mn[ls[id]],mn[rs[id]]);
      	mx[id]=max(mx[ls[id]],mx[rs[id]]);
      }
      il void upd(int &id,int fr,int l,int r,int p){
      	id=New();
      	if(l==r){
      		sum[id]=sum[fr]^1;
      		return ;
      	}
      	int mid=(l+r)>>1;
      	if(p<=mid){
      		rs[id]=rs[fr];
      		upd(ls[id],ls[fr],l,mid,p);
      	}
      	else{
      		ls[id]=ls[fr];
      		upd(rs[id],rs[fr],mid+1,r,p);
      	}
      	pushup(id);
      }
      il int merge(int p,int q,int l,int r){
      	if(!p||!q){
      		return p+q;
      	}
      	if(l==r){
      		int x=New();
      		mn[x]=min(mn[p],mn[q]);
      		mx[x]=max(mx[p],mx[q]);
      		return x;
      	}
      	int mid=(l+r)>>1,x=New();
      	ls[x]=merge(ls[p],ls[q],l,mid);
      	rs[x]=merge(rs[p],rs[q],mid+1,r);
      	mn[x]=min(mn[ls[x]],mn[rs[x]]);
      	mx[x]=max(mx[ls[x]],mx[rs[x]]);
      	return x;
      }
      il int query(int id,int L,int R,int l,int r){
      	if(l>r||!id){
      		return 0;
      	}
      	if(L>=l&&R<=r){
      		return sum[id];
      	}
      	int mid=(L+R)>>1,res=0;
      	if(l<=mid){
      		res+=query(ls[id],L,mid,l,r);
      	}
      	if(r>mid){
      		res+=query(rs[id],mid+1,R,l,r);
      	}
      	return res;
      }
      il int qmn(int id,int l,int r,int p){
      	if(l==r){
      		return mn[id];
      	}
      	int mid=(l+r)>>1;
      	return p<=mid?qmn(ls[id],l,mid,p):qmn(rs[id],mid+1,r,p);
      }
      il int qmx(int id,int l,int r,int p){
      	if(l==r){
      		return mx[id];
      	}
      	int mid=(l+r)>>1;
      	return p<=mid?qmx(ls[id],l,mid,p):qmx(rs[id],mid+1,r,p);
      }
      il void dfs2(int u,int fa){
      	add(rt[u],1,n,dep[u],bfn[u]);
      	for(int v:e[u]){
      		if(v==fa){
      			continue;
      		}
      		dfs2(v,u);
      		rt[u]=merge(rt[u],rt[v],1,n);
      	}
      	for(pii v:quj[u]){
      		int k=v.fir,id=v.sec;
      		if(id>0){
      			wt[id].l1=qmn(rt[u],1,n,k);
      			wt[id].r1=qmx(rt[u],1,n,k);
      		}
      		else{
      			id=-id;
      			wt[id].l2=qmn(rt[u],1,n,k);
      			wt[id].r2=qmx(rt[u],1,n,k);
      		}
      	}
      }
      namespace cplx{
      	bool end;
      	il double usdmem(){return (&begin-&end)/1048576.0;}
      }
      int main(){
      	ios::sync_with_stdio(0),cin.tie(0);
      	cin>>n;
      	for(int i=1,u,v;i<n;i++){
      		cin>>u>>v;
      		e[u].pb(v),e[v].pb(u);
      	}
      	dfs1(1,0),bfs();
      	cin>>m;
      	for(int i=1,opt,x,y;i<=m;i++){
      		cin>>opt>>x;
      		wt[i].opt=opt,wt[i].x=x;
      		if(opt==2){
      			cin>>y;
      			wt[i].y=y;
      			if((y&1)||!y){
      				continue;
      			}
      			y>>=1;
      			if(y>=dep[x]){
      				continue;
      			}
      			x=ganc(wt[i].x,y);
      			quj[x].pb(mp(dep[wt[i].x],i));
      			x=ganc(wt[i].x,y-1);
      			quj[x].pb(mp(dep[wt[i].x],-i));
      		}
      	}
      	mn[0]=inf,mx[0]=-inf;
      	dfs2(1,0);
      	tot=0;
      	build(rt[0],1,n);
      	for(int i=1,opt,x,y;i<=m;i++){
      		opt=wt[i].opt,x=wt[i].x,y=wt[i].y;
      		switch(opt){
      			case 1:{
      				upd(rt[i],rt[i-1],1,n,bfn[x]);
      				break;
      			}
      			case 2:{
      				rt[i]=rt[i-1];
      				if(y&1){
      					cout<<"0\n";
      				}
      				else if(!y){
      					cout<<query(rt[i],1,n,bfn[x],bfn[x])<<"\n";
      				}
      				else{
      					y>>=1;
      					if(y>=dep[x]){
      						cout<<"0\n";
      					}
      					else{
      						cout<<query(rt[i],1,n,wt[i].l1,wt[i].l2-1)+query(rt[i],1,n,wt[i].r2+1,wt[i].r1)<<"\n";
      					}
      				}
      				break;
      			}
      			default:{
      				rt[i]=rt[x];
      				break;
      			}
      		}
      	}
      	return 0;
      }
      }
      int main(){return asbt::main();}
      
      posted @ 2025-02-17 21:40  zhangxy__hp  閱讀(14)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲天堂伊人久久a成人| 九九热在线精品免费视频| 在线播放深夜精品三级| 乱人伦人妻中文字幕| 香港特级三A毛片免费观看| 72种姿势欧美久久久久大黄蕉| 精品国产成人三级在线观看| 太和县| 亚洲精品自产拍在线观看动漫| 东京热人妻丝袜无码AV一二三区观| 一区二区三区四区黄色片| 日韩有码中文在线观看| 亚洲精品不卡无码福利在线观看| 欧美大肥婆大肥bbbbb| 午夜国产精品福利一二| 国产真人性做爰久久网站| 国产三级国产精品久久成人| 免费看女人与善牲交| 久久精品国产亚洲av天海翼| 精品无码国产污污污免费| 小雪被老外黑人撑破了视频| 日本一区二区三区免费播放视频站| 久久综合色一综合色88欧美| 丝袜老师办公室里做好紧好爽| 美女人妻激情乱人伦| 亚洲人成网线在线播放VA| 德格县| 国产午夜福利精品视频| 国语精品国内自产视频| 日本熟妇乱一区二区三区| 黑人巨大AV在线播放无码| 激情综合五月网| 免费观看欧美猛交视频黑人| 国产综合精品一区二区三区| 国产日产亚洲系列av| 办公室强奷漂亮少妇视频| 国产三级精品三级在线观看| 99久久亚洲综合精品成人网| 欧美大屁股xxxx高跟欧美黑人| 亚洲av本道一区二区| 欧美韩中文精品有码视频在线 |