"Bzoj 2243" [SDOI2011] Staining

Source: Internet
Author: User

2243: [SDOI2011] Dyeing time limit: Sec Memory Limit: MB
Submit: 2291 Solved: 890
[Submit] [Status] Description

< Span style= "font-family: Song body" > given a tree with n Nodes and operation with 2

< Span lang= "en-US" >1 a to node b All points on the path are dyed color c ;

< Span lang= "en-US" >2 a to node b path on the number of color segments (continuous same color is considered the same paragraph), such as" 112221 " by 3 segment: " 11 " 222 " 1

please write a program to complete this in turn m operation.

Input

The first line contains 2 an integer N and the m , representing the number of nodes and operands, respectively;

< Span style= "font-family: Song Body" > The second line contains n positive integer representation n nodes

< Span style= "FONT-SIZE:14PX; Font-family:arial,verdana,helvetica,sans-serif "> below &NBSP; line contains two integers per line x " Span style= "font-family: Arial" > and y x y There is a non-edge.

< Span style= "FONT-SIZE:14PX; Font-family:arial,verdana,helvetica,sans-serif "> below &NBSP; row each row describes an action:

< Span lang= "en-us" > "C a b C" Indicates that this is a staining operation, put the node a to node b All points on the path (including a and b ) are dyed color c

"Q a B" indicates that this is a query operation that asks the node a to the node b (including a and the b ) The number of color segments on the path.

Output

For each query operation, output one line of answers.

Sample Input6 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 Output3

1

2
HINT

Number n<=10^5, operand m<=10^5, all color c is an integer and between [0, 10^9].

Source

First round Day1



Tree chain split + lazy tag delivery for segment tree


Let's say something about the two actions I have done:

1.C (Paint):

Maintains a variable Modi, indicating how much has been modified, and if modi=-1 indicates that it has not been modified.


As long as you find the interval to be modified in the segment tree, assign a value to the Modi, and then change it to PUSH_UP


2.Q (Query):

The LCA is first found and then the same is calculated for the heavy chains where you and V are located:


As long as TOP[U]!=TOP[LCA] adds the number of color segments for the current point to Top[u].


Note that you want to record p, which indicates who the highest point in the previous calculation was. So if the color of the current calculated lowest point is equal to the color of p, ans--。


TOP[U]=TOP[LCA], plus the number of color segments from the U to LCA, the same treatment for p.


Finally, the sum of the calculated results from U and v minus 1 (because the LCA is repeated two times) is the answer.

< see comments in Code >


#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include < cstdlib> #include <vector> #include <cmath> #define PB push_back#define N 100005using namespace Std;struct Segtree{int Modi,l,r,lc,rc,cs;} A[n*3];vector<int> v[n];int siz[n],n,m,son[n],fa[n],dep[n],top[n],id[n],co[n],cc[n],num;void dfs1 (int x,int F , int de) {siz[x]=1;son[x]=0;fa[x]=f;dep[x]=de;for (int i=0;i<v[x].size (); i++) if (v[x][i]!=fa[x]) {int u=v[x][i]; DFS1 (u,x,de+1); Siz[x]+=siz[u];if (Siz[son[x]]<siz[u]) son[x]=u;} void dfs2 (int x,int tp) {top[x]=tp;id[x]=++num;if (son[x]) DFS2 (SON[X],TP); for (int i=0;i<v[x].size (); i++) {int u=v[x ][i];if (u==fa[x]| | U==SON[X]) CONTINUE;DFS2 (u,u);}}  void Push_down (int x) {if (!x) return;if (a[x].modi!=-1) {a[x].lc=a[x].rc=a[x].modi; A[x].cs=1;if (A[X].L==A[X].R)//attention to the special treatment of leaf nodes {A[x].modi=-1;return;} A[x<<1].modi=a[x<<1|1].modi=a[x].modi;a[x].modi=-1;}} void push_up (int x) {if (!x| | A[X].L==A[X].R) Return;push_dowN (x<<1), Push_down (x<<1|1); Be sure to pass the a[x].lc=a[x<<1].lc,a[x].rc=a[x<<1|1].rc;a[x].cs=a[x<<1].cs+a[x<<1|1].cs;if first (a[x ].CS&GT;1&AMP;&AMP;A[X&LT;&LT;1].RC==A[X&LT;&LT;1|1].LC) a[x].cs--;} void Build (int x,int l,int r) {a[x].l=l,a[x].r=r,a[x].modi=-1;if (l==r) {A[x].lc=a[x].rc=cc[l];a[x].cs=1;return;} int m= (L+R) >>1; Build (X&LT;&LT;1,L,M); Build (x<<1|1,m+1,r);p ush_up (x);} void Modify (int x,int l,int r,int c) {if (a[x].l>=l&&a[x].r<=r) {A[x].modi=c;return;} Push_down (x); int m= (A[X].L+A[X].R) >>1;if (l<=m) Modify (x<<1,l,r,c); if (r>m) Modify (x<<1|1,l , r,c);p ush_up (x);} void Paint (int u,int v,int c) {int Tp1=top[u],tp2=top[v];while (TP1!=TP2) {if (DEP[TP1]&LT;DEP[TP2]) swap (TP1,TP2), swap ( U,V); Modify (1,ID[TP1],ID[U],C); u=fa[tp1];tp1=top[u];} if (u==v) {Modify (1,id[u],id[u],c); return;} if (Dep[u]>dep[v]) swap (U,V); Modify (1,id[u],id[v],c); return;} int Count (int x,int l,int r) {push_down (x); if (a[x].l==l&&a[x].r==r) RetuRN A[x].cs; int m= (A[X].L+A[X].R) >>1;if (r<=m) return count (X<<1,l,r), if (l>m) return count (X<<1|1,l,r); int Ans=count (x<<1,l,m) +count (x<<1|1,m+1,r), if (A[x<<1].rc==a[x<<1|1].lc&&ans >1) Ans--;return ans;} int Getcolor (int x,int p) {push_down (x); if (a[x].l==p&&a[x].r==p) return a[x].lc;int m= (A[X].L+A[X].R) >> 1;if (p<=m) return Getcolor (x<<1,p), Else return Getcolor (x<<1|1,p);} int Query (int u,int v) {int uu=u,vv=v;int ans=0,tp1=top[u],tp2=top[v];while (TP1!=TP2)//Find Lca{if (dep[tp1]<de P[TP2]) Swap (TP1,TP2), swap (UU,VV); uu=fa[tp1];tp1=top[uu];}       int lca=tp1,h; Here the H is Lca,lca is Top[lca]if (DEP[UU]&GT;DEP[VV]) h=vv;else h=uu;tp1=top[u],tp2=top[v];int p=0;while (TP1!=LCA)//Starting from U {Ans=ans+count (1,id[tp1],id[u]), if (P&&getcolor (1,p) ==getcolor (1,id[u]) ans--;p =id[tp1];u=fa[tp1];tp1= Top[u];} Ans+=count (1,id[h],id[u]), if (P&&getcolor (1,p) ==getcolor (1,id[u]) ans--;p =0;while (TP2!=LCA)//starting from V {ans=ans+count (1,id[tp2],id[v]), if (P&&getcolor (1,p) ==getcolor (1,id[v]) ans--;p =id[tp2];v=fa[ TP2];TP2=TOP[V];}       Ans+=count (1,id[h],id[v]); if (P&&getcolor (1,p) ==getcolor (1,id[v]) ans--;ans--; LCA this point was calculated two times for return ans;} 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++) {in T x,y;scanf ("%d%d", &x,&y); V[x].pb (y), V[Y].PB (x);} NUM=0;DFS1 (1,0,1);d FS2, for (int i=1;i<=n;i++) cc[id[i]]=co[i]; Build (1,1,n), while (m--) {char s[10];int x,y,z;scanf ("%s", s), if (s[0]== ' C ') {scanf ("%d%d%d", &x,&y,&z); Paint (x, y, z);} ELSE{SCANF ("%d%d", &x,&y);p rintf ("%d\n", Query (x, y));}} return 0;}



Sentiment:

1.CE for half an hour did not find out the wrong.


Check it out. The name of the function and the compiler template are duplicated, and the first letter of all the functions is capitalized.


The first letter of all function procedures will be capitalized in the future!



In the 2.wa:query I counted the number of colors that you and V have reached Top[lca], in fact, the LCA is on the line.

You have to be careful ...


3. For the problem with the lazy mark in Push_down and PUSH_UP to special consideration of leaf node no son and A[0]!

"Bzoj 2243" [SDOI2011] Staining

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.