【BZOJ2243】 [SDOI2011]染色

Description

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

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

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

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

Input

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

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

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

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

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

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

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]之間。

【分析】
還是樹鏈剖分,主要是線段樹那里,要記錄最左邊的顏色和最右邊的顏色,合并的時候看看中間相接部分顏色是否相同,如果相同ans-1.
詢問的時候是要重鏈、輕邊的跳的,也是要記錄左右的顏色,判斷顏色是否相同。
代碼如下:
  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<iostream>
  5 #include<algorithm>
  6 using namespace std;
  7 #define Maxn 100010
  8 
  9 struct node
 10 {
 11     int x,y,next;
 12 }t[2*Maxn];int len=0;
 13 
 14 int c[Maxn],fa[Maxn],size[Maxn],first[Maxn],dep[Maxn];
 15 int top[Maxn],w[Maxn],son[Maxn];
 16 int wl=0;
 17 
 18 void ins(int x,int y)
 19 {
 20     t[++len].x=x;t[len].y=y;
 21     t[len].next=first[x];first[x]=len;
 22 }
 23 
 24 struct nnode
 25 {
 26     int l,r,lc,rc,cl,cr,sum,lazy;
 27 }tr[2*Maxn];int tl=0;
 28 
 29 void dfs1(int x,int f)
 30 {
 31     dep[x]=dep[f]+1;
 32     size[x]=1;fa[x]=f;son[x]=0;
 33     for(int i=first[x];i;i=t[i].next) if(t[i].y!=f)
 34     {
 35         dfs1(t[i].y,x);
 36         size[x]+=size[t[i].y];
 37         if(size[t[i].y]>size[son[x]]) son[x]=t[i].y;
 38     }
 39 }
 40 
 41 void dfs2(int x,int tp)
 42 {
 43     top[x]=tp;w[x]=++wl;
 44     if(size[x]!=1) dfs2(son[x],tp);
 45     for(int i=first[x];i;i=t[i].next) if(t[i].y!=fa[x]&&t[i].y!=son[x])
 46     {
 47         dfs2(t[i].y,t[i].y);
 48     }
 49 }
 50 
 51 int build(int l,int r)
 52 {
 53     int x=++tl;
 54     tr[x].l=l;tr[x].r=r;tr[x].lazy=-1;tr[x].sum=0;
 55     if(l!=r)
 56     {
 57         int mid=(l+r)>>1;
 58         tr[x].lc=build(l,mid);
 59         tr[x].rc=build(mid+1,r);
 60     }
 61     return x;
 62 }
 63 
 64 void upd(int x)
 65 {
 66     if(tr[x].lazy==-1) return;
 67     tr[x].sum=1;tr[x].cl=tr[x].cr=tr[x].lazy;
 68     if(tr[x].l!=tr[x].r)
 69     {
 70         tr[tr[x].lc].lazy=tr[x].lazy;
 71         tr[tr[x].rc].lazy=tr[x].lazy;
 72     }
 73     tr[x].lazy=-1;
 74 }
 75 
 76 void change(int x,int l,int r,int y)
 77 {
 78     if(tr[x].l==l&&tr[x].r==r)
 79     {
 80         tr[x].lazy=y;
 81         return;
 82     }
 83     upd(x);
 84     int mid=(tr[x].l+tr[x].r)>>1;
 85     if(r<=mid) change(tr[x].lc,l,r,y);
 86     else if(l>mid) change(tr[x].rc,l,r,y);
 87     else
 88     {
 89         change(tr[x].lc,l,mid,y);
 90         change(tr[x].rc,mid+1,r,y);
 91     }
 92     upd(tr[x].lc);upd(tr[x].rc);
 93     tr[x].cl=tr[tr[x].lc].cl;
 94     tr[x].cr=tr[tr[x].rc].cr;
 95     tr[x].sum=tr[tr[x].lc].sum+tr[tr[x].rc].sum;
 96     if(tr[tr[x].lc].cr==tr[tr[x].rc].cl) tr[x].sum--;
 97 }
 98 
 99 void ffind(int x,int y,int z)
100 {
101     int f1=top[x],f2=top[y];
102     while(f1!=f2)
103     {
104         if(dep[f1]<dep[f2]) 
105         {
106             swap(f1,f2);
107             swap(x,y);
108         }
109         change(1,w[f1],w[x],z);
110         x=fa[f1];
111         f1=top[x];
112     }
113     if(dep[x]<dep[y]) swap(x,y);
114     change(1,w[y],w[x],z);
115 }
116 
117 int q1,q2,a1,a2;
118 int queryt(int x,int l,int r)
119 {
120     upd(x);
121     if(tr[x].l==l&&tr[x].r==r)
122     {
123         if(q1==tr[x].l) a1=tr[x].cl;
124         if(q2==tr[x].r) a2=tr[x].cr;
125         return tr[x].sum;
126     }
127     int mid=(tr[x].l+tr[x].r)>>1;
128     if(r<=mid) return queryt(tr[x].lc,l,r);
129     if(l>mid) return queryt(tr[x].rc,l,r);
130     int ans=queryt(tr[x].lc,l,mid)+queryt(tr[x].rc,mid+1,r);
131     if(tr[tr[x].lc].cr==tr[tr[x].rc].cl) ans--;
132     return ans;
133 }
134 
135 int query(int x,int y)
136 {
137     int cl=-1,cr=-1,f1=top[x],f2=top[y];
138     int ans=0;
139     while(f1!=f2)
140     {
141         if(dep[f1]>=dep[f2])
142         {
143             q1=w[f1];q2=w[x];
144             ans+=queryt(1,w[f1],w[x]);
145             if(a2==cl) ans--;
146             cl=a1;
147             x=fa[f1];f1=top[x];
148         }
149         else
150         {
151             q1=w[f2];q2=w[y];
152             ans+=queryt(1,w[f2],w[y]);
153             if(a2==cr) ans--;
154             cr=a1;
155             y=fa[f2];f2=top[y];
156         }
157     }
158     if(dep[x]<=dep[y])
159     {
160         q1=w[x];q2=w[y];
161         ans+=queryt(1,w[x],w[y]);
162         if(cl==a1) ans--;
163         if(cr==a2) ans--;
164     }
165     else
166     {
167         q1=w[y];q2=w[x];
168         ans+=queryt(1,w[y],w[x]);
169         if(cr==a1) ans--;
170         if(cl==a2) ans--;
171     }
172     return ans;
173 }
174 
175 int main()
176 {
177     int n,m;
178     scanf("%d%d",&n,&m);
179     for(int i=1;i<=n;i++) scanf("%d",&c[i]);
180     memset(first,0,sizeof(first));
181     for(int i=1;i<n;i++)
182     {
183         int x,y;
184         scanf("%d%d",&x,&y);
185         ins(x,y);ins(y,x);
186     }
187     dfs1(1,0);
188     dfs2(1,1);
189     build(1,n);
190     for(int i=1;i<=n;i++) change(1,w[i],w[i],c[i]);
191     char s[10];
192     while(m--)
193     {
194         scanf("%s",s);
195         if(s[0]=='Q')
196         {
197             int x,y;
198             scanf("%d%d",&x,&y);
199             printf("%d\n",query(x,y));
200         }
201         else
202         {
203             int x,y,z;
204             scanf("%d%d%d",&x,&y,&z);
205             ffind(x,y,z);
206         }
207     }
208     return 0;
209 }
[BZOJ2243]

?

2016-05-12?16:34:01

轉載于:https://www.cnblogs.com/Konjakmoyu/p/5486202.html

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

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

相關文章

jquery easyui DataGrid 數據表格 屬性

擴展自 $.fn.panel.defaults &#xff0c;用 $.fn.datagrid.defaults 重寫了 defaults 。 依賴 panelresizablelinkbuttonpagination用法 1. <table id"tt"></table> 1. $(#tt).datagrid({ 2. url:datagrid_data.json, 3. columns:[…

C語言筆試題總結

1. 下面這段代碼的輸出是多少(在32位機上). char *p; // 4 char *q[20]; // 80 char *m[20][20]; // 1600 int (*n)[10]; // 4 struct MyStruct { char dda; double dda1; int type ; }&#xff1b; MyStruct k; // 24 printf("%d %d %d %d",sizeof(p),siz…

第五次作業

學習時間新增代碼行博客發表量知識總結 第十周5801HTML5 C和C 一般用于服務端的服務程序開發&#xff0c;硬件編程開發&#xff0c;系統等等大量框架要用到的。JAVA&#xff0c;學好這個可以開發移動設備程序&#xff0c;JSP網頁程序。C#&#xff0c;學了這個可以開發Winform&a…

數字信號處理的fpga實現_FPGA數字信號處理:通信類I/Q信號及產生

大俠好&#xff0c;歡迎來到FPGA技術江湖&#xff0c;江湖偌大&#xff0c;相見即是緣分。大俠可以關注FPGA技術江湖&#xff0c;在“闖蕩江湖”、"行俠仗義"欄里獲取其他感興趣的資源&#xff0c;或者一起煮酒言歡。大俠好&#xff0c;“寧夏李治廷”再一次和各位見…

iic通訊協議

IIC總線 一般串行數據通訊都有時鐘和數據之分,有異步和同步之別. 有單線,雙線和三線等. I2C肯定是2線的(不算地線). I2C協議確實很科學,比3/4線的SPI要好,當然線多通訊速率相對就快了. I2C的原則是: 在SCL1(高電平)時,SDA千萬別忽悠!!! 否則,SDA下跳則"判罰"為&…

使用 Python 切割圖片

剛好我有張 PNG 圖片需要均勻切割&#xff0c;剛好我不會 PhotoShop&#xff0c;剛好我想用 Python 來練練手。 于是擼袖子碼腳本。 import os from PIL import Imagedef splitimage(src, rownum, colnum, dstpath):img Image.open(src)w, h img.sizeif rownum < h and co…

python數據分析知識點_Python數據分析--Pandas知識點(三)

本文主要是總結學習pandas過程中用到的函數和方法, 在此記錄, 防止遺忘. 下面將是在知識點一, 二的基礎上繼續總結. 前面所介紹的都是以表格的形式中展現數據, 下面將介紹Pandas與Matplotlib配合繪制出折線圖, 散點圖, 餅圖, 柱形圖, 直方圖等五大基本圖形. Matplotlib是python…

SPI通訊協議

SPI&#xff1a;高速同步串行口。是一種標準的四線同步雙向串行總線。 SPI&#xff0c;是英語Serial Peripheral interface的縮寫&#xff0c;顧名思義就是串行外圍設備接口。是Motorola首先在其MC68HCXX系列處理器上定義的。SPI接口主要應用在 EEPROM&#xff0c;FLASH&#x…

基于MVVM的知乎日報應用安卓源碼

使用data binding , dagger2 , retrofit2和rxjava實現的&#xff0c;基于MVVM的知乎日報APP運行效果&#xff1a; <ignore_js_op> 使用說明&#xff1a; 項目結構android data binding來實現MVVM。dagger2來完成依賴注入。retrofit2rxjava實現restful的http請求。第三方類…

F#創建者Don Syme談F#設計原則

在.Net Fringe 2016大會上&#xff0c;F#創建者Don Syme談了他對F#現狀的看法以及F#的二元性。F#是以一個為面向對象語言構建的運行時為基礎構建的函數式語言。\\F#是2010年發布的&#xff0c;遵循開源許可協議。F#比.Net更早地踏上了開源之路&#xff0c;C#和.Net在2015年才開…

php簽入html出來的影響seo嗎_搜索引擎優化_SEO必備6大技能+SEO誤區講解!

大家好&#xff0c;我是逆冬&#xff0c;今天來分享一下實戰SEO需要掌握什么樣的技能以及SEO知識誤區&#xff0c;本篇文章僅代表逆冬本人幾年的經驗、不見得適合每一個SEOer!下面就讓逆冬本人來分析一下實戰型SEO到底需要掌握什么技能。第1點&#xff1a;SEO需要不需要熟練掌握…

編寫linux驅動程序步驟

一、建立Linux驅動框架&#xff08;裝載、卸載Linux驅動&#xff09; Linux內核在使用驅動時首先要裝載驅動&#xff0c;在裝載過程中進行一些初始化動作&#xff08;建立設備文件、分配內存等&#xff09;&#xff0c;在驅動程序中需提供相應函數來處理驅動初始化工作&#xf…

一種M2M業務的架構及實現M2M業務的方法

http://www.cnblogs.com/coryxie/p/3849764.html 技術領域 [0001] 本發明涉及通信技術領域&#xff0c;尤其涉及一種M2M業務的架構及實現M2M業務的方法。 背景技術 [0002] 隨著通信技術的飛速發展以及通信技術與互聯網技術的進一步融合&#xff0c;移動業務以及移動互聯網技術普…

第二章 mybatis使用注解實現in查詢(mysql)

mybatis實現in查詢&#xff0c;兩種方法&#xff1a; xml形式&#xff08;推薦&#xff09;注解方式&#xff08;個人喜歡注解&#xff0c;但是in場景可能不太適合注解&#xff09;代碼&#xff1a; 1 Select("<script>" 2 "SELECT ID…

python面試代碼題_python面試基礎篇80題

1.為什么學習python?3.Python和Java、PHP、C、C#、C等其他語言的對比&#xff1f; C語言由于其底層操作特性和歷史的積累&#xff0c;在嵌入式領域是當之無愧的王者。 PHP跨平臺&#xff0c;性能優越&#xff0c;跟linux/unix結合比跟windows結合性能強45%,開發成本低,php5已經…

主設備號與次設備號以及申請

一個字符設備或者塊設備都有一個主設備號和次設備號。主設備號和次設備號統稱為設備號。主設備號用來表示一個特定的驅動程序。次設備號用來表示使用該驅動程序的各設備。例如一個嵌入式系統&#xff0c;有兩個LED指示燈&#xff0c;LED燈需要獨立的打開或者關閉。那么&#xf…

javascript 變量作用域

為什么80%的碼農都做不了架構師&#xff1f;>>> javascript中的變量的作用域不同于java/c的變量規則。 1、在java/c中&#xff0c;如果有一個全局變量與一個局部變量重名&#xff0c;那么在局部變量的作用域中&#xff0c;局部變量會覆蓋掉全局變量的值。當離開局部…

七月算法--12月機器學習在線班-第五次課筆記—回歸

七月算法--12月機器學習在線班-第五次課筆記—回歸 七月算法&#xff08;julyedu.com&#xff09;12月機器學習在線班學習筆記 http://www.julyedu.com 轉載于:https://www.cnblogs.com/sweet-dew/p/5491271.html

集合添加元素python_Python基礎:列表、字典、元組、集合、添加和刪除元素,增刪...

列表&#xff08;有序&#xff09; 添加 list.append(元素)&#xff1a;在列表末尾添加新的元素 list.extend(seq)&#xff1a;在列表末尾一次性追加另一個序列中的多個值 –seq可以是列表、元組、字典&#xff0c;若為字典,則僅會將鍵(key)作為元素依次添加至原列表的末尾。 l…

file_operations結構體分析 (設備文件的操作)

linux設備驅動中file_operations結構體分析 struct module *owner第一個 file_operations 成員根本不是一個操作; 它是一個指向擁有這個結構的模塊的指針. 這個成員用來在它的操作還在被使用時阻止模塊被卸載. 幾乎所有時間中, 它被簡單初始化為 THIS_MODULE, 一個在 <Linux…