BZOJ 2243 染色(樹鏈剖分好題)

2243: [SDOI2011]染色

Time Limit:?20 Sec??Memory Limit:?512 MB
Submit:?7971??Solved:?2990
[Submit][Status][Discuss]

Description

?

給定一棵有n個節點的無根樹和m個操作,操作有2類:

1、將節點a到節點b路徑上所有點都染成顏色c

2、詢問節點a到節點b路徑上的顏色段數量(連續相同顏色被認為是同一段),如“1122213段組成:“11、“222和“1

請你寫一個程序依次完成這m個操作。

?

Input

第一行包含2個整數nm,分別表示節點數和操作數;

第二行包含n個正整數表示n個節點的初始顏色

下面?行每行包含兩個整數xy,表示xy之間有一條無向邊。

下面?行每行描述一個操作:

“C a b c”表示這是一個染色操作,把節點a到節點b路徑上所有點(包括ab)都染成顏色c

“Q a b”表示這是一個詢問操作,詢問節點a到節點b(包括ab)路徑上的顏色段數量。

?

Output

對于每個詢問操作,輸出一行答案。

?

Sample Input

6 5

2 2 1 2 1 1

1 2

1 3

2 4

2 5

2 6

Q 3 5

C 2 1 1

Q 3 5

C 5 1 2

Q 3 5

Sample Output

3

1

2

HINT

?

數N<=10^5,操作數M<=10^5,所有的顏色C為整數且在[0, 10^9]之間。

?

?

題目鏈接:BZOJ 2243

做了幾道普通的樹鏈剖分維護邊權、點權,查詢路徑的題目,感覺并沒有什么特點,然而這題比較有意思,求路徑上連續顏色有幾段,顯然用線段樹的話只要維護當前區間最左和最右的顏色,左右子區間即可推出父區間的答案:左邊段數+右邊段數-(左區間右端點顏色==右區間左端點顏色)。然后統計的時候也要利用這個思想——線段樹的query與樹鏈剖分中記錄u與v上升區間段數的同時也與u、v最后上升的區間最左端點顏色比較得到答案。

代碼:

#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define fin(name) freopen(name,"r",stdin)
#define fout(name) freopen(name,"w",stdout)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = 100010;
struct seg
{int l, mid, r;int lc, rc;int s, tag;
};
struct edge
{int to, nxt;edge() {}edge(int _to, int _nxt): to(_to), nxt(_nxt) {}
};
edge E[N << 1];
seg T[N << 2];
int head[N], tot;
int sz[N], fa[N], son[N], top[N], dep[N], idx[N], ts;
int arr[N];
int Rc, Lc;void init()
{CLR(head, -1);tot = 0;ts = 0;
}
void add(int s, int t)
{E[tot] = edge(t, head[s]);head[s] = tot++;
}
void dfs1(int u, int f, int d)
{sz[u] = 1;fa[u] = f;son[u] = -1;dep[u] = d;for (int i = head[u]; ~i; i = E[i].nxt){int v = E[i].to;if (v != f){dfs1(v, u, d + 1);sz[u] += sz[v];if (son[u] == -1 || sz[son[u]] < sz[v])son[u] = v;}}
}
void dfs2(int u, int tp)
{idx[u] = ++ts;top[u] = tp;if (~son[u])dfs2(son[u], tp);for (int i = head[u]; ~i; i = E[i].nxt){int v = E[i].to;if (v != fa[u] && v != son[u])dfs2(v, v);}
}
void pushup(int k)
{T[k].s = T[LC(k)].s + T[RC(k)].s - (T[LC(k)].rc == T[RC(k)].lc);T[k].lc = T[LC(k)].lc;T[k].rc = T[RC(k)].rc;
}
void pushdown(int k)
{if (T[k].tag == -1)return ;T[LC(k)].tag = T[RC(k)].tag = T[k].tag;T[LC(k)].lc = T[LC(k)].rc = T[k].tag;T[RC(k)].lc = T[RC(k)].rc = T[k].tag;T[LC(k)].s = T[RC(k)].s = 1;T[k].tag = -1;
}
void build(int k, int l, int r)
{T[k].l = l;T[k].r = r;T[k].mid = MID(l, r);T[k].lc = T[k].rc = 0;T[k].tag = -1;T[k].s = 0;if (l == r)return ;build(LC(k), l, T[k].mid);build(RC(k), T[k].mid + 1, r);
}
void update(int k, int l, int r, int c)
{if (l <= T[k].l && T[k].r <= r){T[k].tag = c;T[k].lc = T[k].rc = c;T[k].s = 1;}else{pushdown(k);if (r <= T[k].mid)update(LC(k), l, r, c);else if (l > T[k].mid)update(RC(k), l, r, c);else{update(LC(k), l, T[k].mid, c);update(RC(k), T[k].mid + 1, r, c);}pushup(k);}
}
int query(int k, int l, int r, int L, int R)
{if (L == T[k].l)Lc = T[k].lc;if (R == T[k].r)Rc = T[k].rc;if (l <= T[k].l && T[k].r <= r)return T[k].s;else{pushdown(k);if (r <= T[k].mid)return query(LC(k), l, r, L, R);else if (l > T[k].mid)return query(RC(k), l, r, L, R);elsereturn query(LC(k), l, T[k].mid, L, R) + query(RC(k), T[k].mid + 1, r, L, R) - (T[LC(k)].rc == T[RC(k)].lc);}
}
int Find(int u, int v)
{int ret = 0;int tu = top[u], tv = top[v];int last_u = -1, last_v = -1;while (tu != tv){if (dep[tu] < dep[tv]){swap(tu, tv);swap(u, v);swap(last_u, last_v);}ret += query(1, idx[tu], idx[u], idx[tu], idx[u]);if (Rc == last_u)--ret;last_u = Lc;u = fa[tu];tu = top[u];}if (dep[u] > dep[v]){swap(u, v);swap(last_u, last_v);}ret += query(1, idx[u], idx[v], idx[u], idx[v]);if (Lc == last_u)--ret;if (Rc == last_v)--ret;return ret;
}
void solve(int u, int v, int c)
{int tu = top[u], tv = top[v];while (tu != tv){if (dep[tu] < dep[tv]){swap(tu, tv);swap(u, v);}update(1, idx[tu], idx[u], c);u = fa[tu];tu = top[u];}if (dep[u] > dep[v])swap(u, v);update(1, idx[u], idx[v], c);
}
int main(void)
{int n, m, a, b, c, i;char ops[10];while (~scanf("%d%d", &n, &m)){init();for (i = 1; i <= n; ++i)scanf("%d", &arr[i]);for (i = 1; i < n; ++i){scanf("%d%d", &a, &b);add(a, b);add(b, a);}dfs1(1, 0, 1);dfs2(1, 1);build(1, 1, n);for (i = 1; i <= n; ++i)update(1, idx[i], idx[i], arr[i]);while (m--){scanf("%s", ops);if (ops[0] == 'Q'){scanf("%d%d", &a, &b);printf("%d\n", Find(a, b));}else{scanf("%d%d%d", &a, &b, &c);solve(a, b, c);}}}return 0;
}

轉載于:https://www.cnblogs.com/Blackops/p/7258037.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/455037.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/455037.shtml
英文地址,請注明出處:http://en.pswp.cn/news/455037.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

processing動態代碼大全_做一張動態海報需要多少步?

人們習慣性地把程序員跟設計師分成兩種不同性質的人&#xff0c;好像程序員就不會有美感&#xff0c;設計師邏輯思維就一定會很弱&#xff0c;但最近幾年我們發現越來越多的程序員學設計&#xff0c;設計師學編程的跨界故事。新媒體藝術家&#xff0c;邱偉豪也是其中一員&#…

【ffmpeg for wince】音視頻編解碼多平臺移植(for window/wince)

from: http://www.cnblogs.com/windwithlife/archive/2009/05/31/1492728.html 終于完成了了第二個Client side原型&#xff08;for Wince)&#xff0c;其中花掉我最多時間的就是ffmpeg的對WINCE的移植。其中有大半時間是由于網上的一些不完整及不正確信息所誤導&#xff0c;…

python實現猴子爬山算法

猴子爬山一只頑猴在一座有N級臺階的小山上爬山跳躍。上山時需從山腳至山頂往上跳N級臺階&#xff0c;一步可跳1級&#xff0c;或跳3級&#xff0c;求上山有多少種不同的跳法&#xff1f; &#xff08;N<50&#xff09; 問題分析: 每一次都可以選擇1,2,3有3種跳法 方法1 直…

指針版 單鏈表復習

#include <bits/stdc.h> #define P pair<int,int> using namespace std;typedef long long LL;typedef struct LNode{int data;struct LNode *nxt; }LNode,*LinkList;bool Linklist_init(LinkList &root){root new LNode; ///分配頭結點&#xff0c;指針域為空…

手寫springboot_Spring Boot 入門教程 | 圖文講解

目錄一、Spring Boot 是什么二、為什么要使用 Spring Boot三、快速入門3.1 創建 Spring Boot 項目3.2 項目結構3.3 引入 Web 依賴3.4 編寫第一個接口3.5 啟動程序&#xff0c;驗證效果四、總結五、GitHub 示例代碼一、Spring Boot 是什么以下截圖自 Spring Boot 官方文檔&#…

lunix 安裝python3

Linux下默認系統自帶python2.6的版本&#xff0c;這個版本被系統很多程序所依賴&#xff0c;所以不建議刪除&#xff0c;如果使用最新的Python3那么我們知道編譯安裝源碼包和系統默認包之間是沒有任何影響的&#xff0c;所以可以安裝python3和python2共存 首先去python官網下載…

手機音視頻應用開發(專注于Symbian、iPhone、Android等跨平臺音視頻應用開發方案)

一款好的手機應用&#xff0c; 能讓用戶在第一分鐘就愛上他&#xff0c; 一款爛的手機應用&#xff0c; 能讓用戶在第一分鐘就要卸載它。 好的應用必須的穩定、快速。市場日益激勵&#xff0c;一個項目的周期是一個漫長的過程&#xff0c;投入的時間、精力、費用。一筆龐大的預…

Colemak布局的實現 Window+Linux+Android

Colemak布局的實現 WindowLinuxAndroid title: ‘Colemak布局的實現’ subtitle: ‘一個極客的鍵盤布局’ tags: entertainment solution 前言 大部分同學使用的鍵盤布局都是QWERTY布局 而科學研究表明,可能這個設計不是最高效率的布局,甚至的有意為了降低打字的效率而研究的…

機器學習之樸素貝葉斯法

轉載請注明出處&#xff1a;http://www.cnblogs.com/Peyton-Li/ 樸素貝葉斯法是機器學習模型中一個比較簡單的模型&#xff0c;實現簡單&#xff0c;比較常用。 是定義在輸入空間上的隨機向量&#xff0c;是定義在輸出空間上的隨機變量。是和的聯合概率分布。訓練數據集由獨立同…

如何讓梯形變成平行四邊形_開放的課堂 創新的天地——平行四邊形的面積教學片段與反思...

一、 課題的確定學生在三年級學過長方形、正方形的面積計算&#xff0c;經歷過從數方格的辦法得出面積計算公式的過程。因此&#xff0c;學生對于面積計算公式的推導有一定的經驗和知識基礎。基于上述考慮&#xff0c;我想完全放手讓學生去研究如何計算平行四邊形的面積。這對學…

bzoj1670【Usaco2006 Oct】Building the Moat 護城河的挖掘

1670: [Usaco2006 Oct]Building the Moat護城河的挖掘 Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 387 Solved: 288[Submit][Status][Discuss]Description 為了防止口渴的食蟻獸進入他的農場&#xff0c;Farmer John決定在他的農場周圍挖一條護城河。農場里一共同擁有N(8…

音視頻編解碼的一些源代碼

音視頻編解碼的一些源代碼 &#xff08;轉&#xff09;資料名稱&#xff1a;音視頻編解碼的一些源代碼 資料成文時間&#xff1a;不詳 語言&#xff1a;英文 頁數&#xff1a;很多 何人所著&#xff08;來源&#xff09;&#xff1a; 文件格式&#xff1a;原代碼 開發工具:vc 說…

Vue之組件之間的數據傳遞

Vue的組件作用域都是孤立的&#xff0c;不允許在子組件的模板內直接引用父組件的數據&#xff0c;必須使用特定的方法才能實現組件之間的數據傳遞。 下列為在vue-cli創建項目中的操作 一父組件向子組件傳遞數據 在Vue中&#xff0c;用props向子組件傳遞數據。 子組件部分&#…

偶然發現一個大佬寫的 React 腳手架,叫Moderate, 用起來很方便

發現一個大佬寫的 React 腳手架&#xff0c;叫Moderate, 用起來很方便 Moderate&#xff0c;意思為適中的&#xff0c;適度的&#xff0c;用這個作為代號&#xff0c;主要取決于他的本名“中用”&#xff0c;其一以貫之的想法就是中庸&#xff0c;秉承著以人為本的態度&#xf…

案例 自動辦公_1300張辦公系列前臺參考圖,請您查收!

設計情報局室內設計師的靈感聚集地關注一個有格調的空間必定有一處高顏值的前臺漂亮的前臺很重要...是空間給人的第一印象一個獨一無二的前臺設計還可以提升整個空間的氣質與逼格連個漂亮的前臺都沒有作為顏控界扛把子的設計師們還怎么混&#xff1f;SO今天小編給大家帶來一份《…

iframe里面的元素觸發父窗口元素事件的jquery代碼 轉

例如父窗口定義了一個事件。 top: $(dom1).bind(topEvent, function(){}); 那么iframe里面的元素怎樣觸發父窗口dom1的事件呢&#xff1f;這樣嗎&#xff1f; $(dom1, parent.document).trigger(topEvent); 看似正確&#xff0c;實則誤導人。 因為父窗口的jquery對象與iframe里…

mplayer 所支持的音視頻編解碼

這里我把mplayer 所支持的音視頻編解碼都羅列出來&#xff0c;方便大家查閱&#xff1b;-----------------------------------------------------------------------------------------------Video codecs:Working video codecscodec namefourcccodecfileoutcommentsFFmpeg Zip…

使用ifconfig取出網卡eth0的ip地址

方法1&#xff1a;sed命令12[rootoldboyedu ~]# ifconfig eth0 |sed -n 2p |seds#^.*addr:##g|sed s# B.*$##g10.0.0.50方法2&#xff1a;cut12[rootoldboyedu ~]# ifconfig eth0|grep inetaddr|cut -d ":" -f2|cut -d " " -f110.0.0.50方法3&#xff1a;…

目標檢測_目標檢測 | Anchor free的目標檢測進階版本

今天說的是《Soft Anchor-Point Object Detection》&#xff0c;其也是最近關于anchor free的目標檢測的論文&#xff0c;作者來自于CMU&#xff0c;一作同樣也是FSAF(2019 CVPR)的作者。該論文的出發點還是在樣本選擇和FPN特征選擇層面。背景Anchor free是目標檢測領域的一個研…

Colly實現豆瓣電影Top250爬取

使用 Colly 實現 豆瓣電影Top250爬取 package mainimport ("encoding/csv""github.com/PuerkitoBio/goquery""github.com/gocolly/colly""log""os""strings""time" )type Movie struct {idx string…