多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > php教程 > [置頂] 【整合】樹鏈剖分模板(線段樹維護)

[置頂] 【整合】樹鏈剖分模板(線段樹維護)

來源:程序員人生   發布時間:2015-04-02 08:12:04 閱讀次數:2799次

原題是SDOI2011染色
反正鏈剖都長得差不多不1樣的就是線段樹根據題自己在查詢和修改里改1改就行了
隨著黃學長學的倍增記錄先人的寫法,和網上不太1樣求不噴
注釋棒棒噠

代碼又長跑的也不快我也是醉了 注釋代碼根據題目不同自己修改 #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define MAXINT 0x7fffffff #define MAXN 100010 #define lchild rt<<1,l,mid #define rchild rt<<1|1,mid+1,r #define ln rt<<1 #define rn rt<<1|1 using namespace std; int n,m; int top,tp; int co[MAXN]; int a,b,color; int deep[MAXN],size[MAXN],chain[MAXN],fa[MAXN][18],num[MAXN]; //deep 深度,size 子樹大小,chain 接的鏈,fa 父親節點,num 點的編號 bool vis[MAXN];//節點是不是已訪問過 char ch[2]; struct seg { int mark;//染色標記 int l,r;//對應左右區間 int data;//色彩段數量 int lc,rc;//區間左右端點色彩 }tree[MAXN*4]; struct edge { int to; edge *next; }e[MAXN*2],*prev[MAXN]; void insert(int u,int v) { e[++top].to=v; e[top].next=prev[u]; prev[u]=&e[top]; } void dfs1(int x)//第1遍DFS處理子樹大小/先人關系/深度 { size[x]=1; vis[x]=1; for (int i=1;i<=17;i++) { if (deep[x]<(1<<i)) break; fa[x][i]=fa[fa[x][i-1]][i-1];//倍增處理先人 } for (edge *i=prev[x];i;i=i->next) { int t=i->to; if (vis[t]) continue; deep[t]=deep[x]+1; fa[t][0]=x; dfs1(t); size[x]+=size[t]; } } void dfs2(int x,int last)//接鏈上編號.last為之前的鏈 { num[x]=++tp; chain[x]=last;//x為當前重子節點 int t=0; for (edge *i=prev[x];i;i=i->next) if (deep[i->to]>deep[x]&&size[t]<size[i->to])//尋覓重子節點 t=i->to; if (!t) return; dfs2(t,last); for (edge *i=prev[x];i;i=i->next) if (deep[i->to]>deep[x]&&i->to!=t) dfs2(i->to,i->to);//在輕子節點上重新接出新的鏈 } /*void push_up(int rt) { tree[rt].lc=tree[ln].lc;tree[rt].rc=tree[rn].rc; tree[rt].data=tree[ln].data+tree[rn].data; if (tree[ln].rc==tree[rn].lc) tree[rt].data--;//左右區間相接處 //色彩相同的話需要把data減1 }*/ /*void push_down(int rt) { if (tree[rt].mark==-MAXINT) return; if (tree[rt].l==tree[rt].r) return; tree[ln].data=tree[rn].data=1; tree[ln].mark=tree[rn].mark=tree[ln].lc=tree[rn].lc=tree[ln].rc=tree[rn].rc=tree[rt].mark; tree[rt].mark=-MAXINT; }*/ void build(int rt=1,int l=1,int r=n) { /*tree[rt].l=l; tree[rt].r=r; tree[rt].data=1; tree[rt].mark=-MAXINT;*/ if (l==r) return; int mid=(l+r)>>1; build(lchild); build(rchild); //push_up(rt); } int lca(int a,int b)//最近公共先人.將鏈提到最近公共先人上 { if (deep[a]<deep[b]) swap(a,b); int t=deep[a]-deep[b]; for (int i=0;i<=17;i++) if (t&(1<<i)) a=fa[a][i]; for (int i=17;i>=0;i--) if (fa[a][i]!=fa[b][i]) { a=fa[a][i]; b=fa[b][i]; } if (a==b) return a; else return fa[a][0]; } void modify(int rt,int l,int r,int col)//修改區間色彩 { push_down(rt); int L=tree[rt].l,R=tree[rt].r; if (L==l&&R==r) { tree[rt].data=1; tree[rt].lc=tree[rt].rc=col; tree[rt].mark=col; return; } int mid=(L+R)>>1; if (r<=mid) modify(ln,l,r,col); else if (l>mid) modify(rn,l,r,col); else { modify(ln,l,mid,col); modify(rn,mid+1,r,col); } push_up(rt); } void Modify(int a,int b,int col)//修改兩點間路徑色彩 { while(chain[a]!=chain[b]) { modify(1,num[chain[a]],num[a],col); a=fa[chain[a]][0]; } modify(1,num[b],num[a],col);//在把鏈上提以后a在b的左邊 //(差不多就是這個意思自己懂就行...) } int query(int rt,int l,int r)//查詢區間色彩段數目 { push_down(rt); int L=tree[rt].l,R=tree[rt].r; if (L==l&&R==r) return tree[rt].data; int mid=(L+R)>>1; if (r<=mid) return query(ln,l,r); else if (mid<l) return query(rn,l,r); else { /*if (tree[ln].rc==tree[rn].lc) return query(ln,l,mid)+query(rn,mid+1,r)⑴; else return query(ln,l,mid)+query(rn,mid+1,r);*/ } } int pointcolor(int rt,int x)//查詢某個點的色彩 (可以看作是查詢權值) { push_down(rt); int L=tree[rt].l,R=tree[rt].r; if (L==R) return tree[rt].lc; int mid=(L+R)>>1; if (x<=mid) return pointcolor(ln,x); else return pointcolor(rn,x); } int Query(int a,int b)//查詢兩點間路徑色彩段數目 { int ret=0; while (chain[a]!=chain[b]) { ret+=query(1,num[chain[a]],num[a]); /* if (pointcolor(1,num[chain[a]])==pointcolor(1,num[fa[chain[a]][0]])) ret--;*/ a=fa[chain[a]][0]; } ret+=query(1,num[b],num[a]); return ret; } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%d",&co[i]); for (int i=1;i<n;i++) { scanf("%d%d",&a,&b); insert(a,b);insert(b,a); } dfs1(1); dfs2(1,1); build(); for (int i=1;i<=n;i++) modify(1,num[i],num[i],co[i]); for (int i=1;i<=m;i++) { scanf("%s",ch); if (ch[0]=='Q') { scanf("%d%d",&a,&b); int t=lca(a,b); printf("%d ",Query(a,t)+Query(b,t)-1); } else { scanf("%d%d%d",&a,&b,&color); int t=lca(a,b); Modify(a,t,color); Modify(b,t,color); } } }
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 久草在线播放视频 | 午夜精品久久久久久久久 | 在线视频国产一区 | 偷拍区小说区图片区另类呻吟 | 多人做人爱视频大全在线观看 | 久久国产精品久久精 | 亚洲精品成人a在线观看 | 亚洲综合一区二区三区四区 | 一级久久 | 又粗又硬又黄又爽的免费视频 | 午色 | 亚洲欧美日韩国产综合久 | 免费欧洲毛片a级视频无风险 | 中文字幕成人在线观看 | 亚洲精品久久久久久下一站 | 久久久网久久久久合久久久久 | 亚洲免费中文 | 伊人久久国产免费观看视频 | 国产一区二区在线视频播放 | 羞羞人成午夜爽爽影院 | 中文字幕在亚洲第一在线 | 亚洲精品视频在线 | www.黄色| 亚洲伦理网站 | 色中色在线视频 | 欧美.亚洲.日本一区二区三区 | 国产精品爱久久久久久久9999 | 中文字幕精品视频在线观看 | 中文字幕天天躁夜夜狠狠综合 | 成人自拍网站 | yy6080私人影院理论 | 亚洲另类中文字幕 | 成人精品国产 | 国产精品久久久久9999赢消 | 国产精品自拍第一页 | 2019国内精品久久久久久 | 亚洲精品一区 | 日韩综合色 | 羞羞动漫免费网站 | a级艳片武则天 | 伊人影院综合在线 |