日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[SCOI2015]情报传递(主席树+lca)

發(fā)布時間:2023/12/15 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [SCOI2015]情报传递(主席树+lca) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

鏈接:https://ac.nowcoder.com/acm/problem/20570
來源:牛客網(wǎng)

輸出描述:
對于每個傳遞情報任務輸出一行,應包含兩個整數(shù),分別是參與傳遞情報的情報員個數(shù)和對該條情報構成威脅的情報員個數(shù)。
輸出的行數(shù)應等于傳遞情報任務的個數(shù),每行僅包含兩個整數(shù),用一個空格隔開。輸出不應包含多余的空行和空格。
示例1
輸入
復制
7
0 1 1 2 2 3 3
6
1 4 7 0
2 1
2 4
2 7
1 4 7 1
1 4 7 3
輸出
復制
5 0
5 2
5 1

具體解釋看代碼:

#include<bits/stdc++.h> #define ll long long using namespace std;const int maxx=2e5+100; struct node{int l;int r;int num; }p[maxx*40]; struct edge{int to,next; }e[maxx<<1]; struct ddd{int x,y,t; }q[maxx]; int head[maxx<<1],dp[maxx][26]; int root[maxx],deep[maxx],val[maxx]; int n,m,tot,rt,ror; /*------------事前準備-------------*/ inline void init() {memset(dp,0,sizeof(dp));memset(val,0,sizeof(val));memset(head,-1,sizeof(head));tot=ror=0; } inline void add(int u,int v) {e[tot].to=v,e[tot].next=head[u],head[u]=tot++; } /*----------主席樹-----------*/ inline int build(int l,int r) {int cur=++ror;p[cur].num=0;if(l==r) return cur;int mid=l+r>>1;p[cur].l=build(l,mid);p[cur].r=build(mid+1,r);return cur; } inline int update(int rot,int l,int r,int pos) {int cur=++ror;p[cur]=p[rot];p[cur].num++;if(l==r) return cur;int mid=l+r>>1;if(pos<=mid) p[cur].l=update(p[rot].l,l,mid,pos);else p[cur].r=update(p[rot].r,mid+1,r,pos);return cur; } inline int query(int lrot,int rrot,int frot,int ffrot,int l,int r,int pos) {if(l>pos) return 0;if(r<=pos) return p[lrot].num+p[rrot].num-p[frot].num-p[ffrot].num;//點差分int mid=l+r>>1;int ret=0;if(pos>=l) ret+=query(p[lrot].l,p[rrot].l,p[frot].l,p[ffrot].l,l,mid,pos);if(pos>mid) ret+=query(p[lrot].r,p[rrot].r,p[frot].r,p[ffrot].r,mid+1,r,pos);return ret; } /*------------dfs------------*/ inline void dfs(int u,int f) {deep[u]=deep[f]+1;dp[u][0]=f;for(int i=1;i<=25;i++){if(dp[u][i-1]) dp[u][i]=dp[dp[u][i-1]][i-1];else break;}root[u]=update(root[f],1,m,val[u]);for(int i=head[u];i!=-1;i=e[i].next){int to=e[i].to;if(to==f) continue;dfs(to,u);} } /*-----------lca-----------*/ inline int get_lca(int x,int y) {if(deep[x]<deep[y]) swap(x,y);int tmp=deep[x]-deep[y];for(int i=0;i<=25;i++){if(tmp&(1<<i)) x=dp[x][i];}if(x==y) return x;for(int i=25;i>=0;i--){if(dp[x][i]!=dp[y][i]){x=dp[x][i];y=dp[y][i];}}return dp[x][0]; } int main() {init();int x,op,y,c;scanf("%d",&n);for(int i=1;i<=n;i++) {scanf("%d",&x);if(x==0) rt=i;add(x,i);add(i,x);}scanf("%d",&m);for(int i=1;i<=n;i++) val[i]=m;//因為轉化之后求得是小于等于某個值的數(shù),所以初始化就要設置為最大值int cnt=0;for(int i=1;i<=m;i++){scanf("%d",&op);if(op==1){scanf("%d%d%d",&x,&y,&c);q[++cnt].x=x,q[cnt].y=y,q[cnt].t=i-c-1;//將所有查詢操作保存下來。}else {scanf("%d",&x);val[x]=i;}}root[0]=build(1,m);deep[0]=0;dfs(rt,0);for(int i=1;i<=cnt;i++){x=q[i].x,y=q[i].y,c=q[i].t;int Lca=get_lca(x,y);printf("%d ",deep[x]+deep[y]-2*deep[Lca]+1);//節(jié)點個數(shù)。printf("%d\n",query(root[x],root[y],root[Lca],root[dp[Lca][0]],1,m,c));}return 0; }

努力加油a啊,(o)/~

總結

以上是生活随笔為你收集整理的[SCOI2015]情报传递(主席树+lca)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。