【BZOJ-3757】蘋果樹 塊狀樹 + 樹上莫隊

來源:互聯網
上載者:User

標籤:

3757: 蘋果樹Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 1305  Solved: 503
[Submit][Status][Discuss]Description

    神犇家門口種了一棵蘋果樹。蘋果樹作為一棵樹,當然是呈樹狀結構,每根樹枝串連兩個蘋果,每個蘋果都可以沿著一條由樹枝構成的路徑連到樹根,而且這樣的路徑只存在一條。由於這棵蘋果樹是神犇種的,所以蘋果都發生了變異,變成了各種各樣的顏色。我們用一個到n之間的正整數來表示一種顏色。樹上一共有n個果。蘋每個蘋果都被編了號碼,號碼為一個1到n之間的正整數。我們用0代表樹根。只會有一個蘋果直接根。

  有許許多多的人來神犇家裡膜拜神犇。可神犇可不是隨便就能膜拜的。前來膜拜神犇的人需要正確回答一個問題,才能進屋膜拜神犇。這個問題就是,從樹上編號為u的蘋果出發,由樹枝走到編號為v的蘋果,路徑上經過的蘋果一共有多少種不同的顏色(包括蘋果u和蘋果v的顏色)?不過神犇注意到,有些來膜拜的人患有色盲症。具體地說,一個人可能會認為顏色a就是顏色b,那麼他們在數蘋果的顏色時,如果既出現了顏色a的蘋果,又出現了顏色b的蘋果,這個人只會算入顏色b,而不會把顏色a算進來。

  神犇是一個好人,他不會強人所難,也就會接受由於色盲症導致的答案錯誤(當然答案在色盲環境下也必須是正確的)。不過這樣神犇也就要更改他原先數顏色的程式了。雖然這對於神犇來說是小菜一碟,但是他想考驗一下你。你能替神犇完成這項任務嗎?

Input輸入第一行為兩個整數n和m,分別代表樹上蘋果的個數和前來膜拜的人數。接下來的一行包含n個數,第i個數代表編號為i的蘋果的顏色Coli。接下來有n行,每行包含兩個數x和y,代表有一根樹枝串連了蘋果x和y(或者根和一個蘋果)。接下來有m行,每行包含四個整數u、v、a和b,代表這個人要數蘋果u到蘋果v的顏色種數,同時這個人認為顏色a就是顏色b。如果a=b=0,則代表這個人沒有患色盲症。Output

輸出一共m行,每行僅包含一個整數,代表這個人應該數出的顏色種數。

Sample Input5 3
1 1 3 3 2
0 1
1 2
1 3
2 4
3 5
1 4 0 0
1 4 1 3
1 4 1 2
Sample Output2
1
2
HINT0<=x,y,a,b<=NN<=500001<=U,V,Coli<=NM<=100000SourceSolution

樹上莫隊裸題,下面來說說樹上莫隊

序列上的莫隊沒什麼好說的,至於樹上莫隊,思想是一樣的

對樹DFS分塊(詳見  BZOJ-1086王室聯邦哦),然後對詢問排序,然後處理就好,那麼就是具體的實現了

至於樹分塊,就是按照DFS時間戳記去搞,所以詢問排序的第一關鍵字就是所在的塊,第二關鍵字就是時間戳記

至於如何把樹上的一條路徑,轉化為一端區間?

首先我們設$S(u,v)$表示$u-v$的路徑上的點集,$LCA(u,v)$表示兩點的最近公用祖先,$root$為樹根

$xor$為集合的對稱差,即  只屬於其中一個集合,而不屬於另一個集合的元素組成的集合

那麼發現$S(u,v)=S(root,u) xor S(root,v) xor LCA(u,v)$  (不懂見哦)

就是節點出現兩次消掉

再有$T(u,v)=S(root, v) xor S(root, u)$

觀察將詢問$curV$移動到$targetV$前後$T(curV, curU)$變化:

$T(curV, curU)=S(root, curV) xor S(root, curU)$

$T(targetV, curU)=S(root, targetV) xor S(root, curU)$

取對稱差:

$T(curV, curU) xor T(targetV, curU)= (S(root, curV) xor S(root, curU)) xor (S(root, targetV) xor S(root, curU))$

由於對稱差的交換律、結合律:

$T(curV, curU) xor T(targetV, curU)= S(root, curV) xorS(root, targetV)$

兩邊同時$xor T(curV, curU)$:

$T(targetV, curU)= T(curV, curU) xor S(root, curV) xor S(root, targetV)$

$T(targetV, curU)=T(curV, curU) xor T(curV, targetV)$

也就是說,更新的時候,$xor T(curV, targetV)$就行了。

即,對$curV$到$targetV$路徑(除開$LCA(curV, targetV))$上的結點,將它們的存在性取反即可。                          ---------------------By  VFK至於路徑上取對稱差?求$S(7,10)$,很顯然$root=1$,$S(1,7)=\left\{1,3,7\right\},S(1,10)=\left\{1,4,8,10\right\}$所以$S(1,7) xor S(1,10)=\left\{3,7,4,8,10\right\}$,$\left\{3,7,4,8,10\right\} xor LCA(7,10)=\left\{1,3,7,4,8,10\right\}=S(7,10)$圖中藍色的路徑表示$S(1,7)$,綠色路徑表示$S(1,10)$,紅色路徑表示$S(7,10)$,黃色圈表示$LCA(7,10)$其餘的都是一樣..詢問間的移動,原理一樣,感受一下就好Code
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>using namespace std;int read(){    int x=0;char ch=getchar();    while(ch<‘0‘||ch>‘9‘) ch=getchar();    while(ch>=‘0‘&&ch<=‘9‘) {x=x*10+ch-‘0‘;ch=getchar();}    return x;}#define maxn 50100#define maxq 100100int n,m,fk,knum,ans,root; struct Edgenode{int to,next;}edge[maxn<<1];int head[maxn],cnt=1;void add(int u,int v){cnt++;edge[cnt].next=head[u];head[u]=cnt;edge[cnt].to=v;}void insert(int u,int v){add(u,v); add(v,u);}int deep[maxn],father[maxn][25],dfsx,stack[maxn],top,rt[maxn],an[maxq],p[maxn];struct Pointnode{int dfs,col;}po[maxn];struct Asknode{    int a,b,u,v,id;    bool operator < (const Asknode & A) const        {            if(rt[u]==rt[A.u]) return po[v].dfs<po[A.v].dfs;                else return rt[u]<rt[A.u];        }}q[maxq];bool visit[maxn];int DFS(int now){    int size=0;    po[now].dfs=++dfsx;    for (int i=1; i<=20; i++)        if (deep[now]>=(1<<i))            father[now][i]=father[father[now][i-1]][i-1];    for (int i=head[now]; i; i=edge[i].next)        if (edge[i].to!=father[now][0])            {                deep[edge[i].to]=deep[now]+1;                father[edge[i].to][0]=now;                size+=DFS(edge[i].to);                  if (size>=fk)                    {                        knum++;                        for(int j=1; j<=size; j++)                            rt[stack[top--]]=knum;                        size=0;                    }               }    stack[++top]=now;    return size+1;}   int LCA(int x,int y){    if (deep[x]<deep[y]) swap(x,y);    int dd=deep[x]-deep[y];    for (int i=0; i<=20; i++)        if (dd&(1<<i) && dd>=(1<<i)) x=father[x][i];    for (int i=20; i>=0; i--)        if (father[x][i]!=father[y][i])             x=father[x][i],y=father[y][i];    if (x==y) return x; else return father[x][0];}void reserv(int x){    if (!visit[x]) {visit[x]=1; p[po[x].col]++; if (p[po[x].col]==1) ans++;}        else {visit[x]=0; p[po[x].col]--; if (p[po[x].col]==0) ans--;}}void work(int u,int v){    while (u!=v)        if (deep[u]>deep[v]) reserv(u),u=father[u][0];            else reserv(v),v=father[v][0];}int main(){    n=read(),m=read(); fk=sqrt(n);    for (int i=1; i<=n; i++) po[i].col=read();    for (int u,v,i=1; i<=n; i++)        {            u=read(),v=read();            if (!u) root=v;                else if (!v) root=u;                    else insert(u,v);        }    DFS(root);    knum++;     while (top) rt[stack[top--]]=knum;    for (int i=1; i<=m; i++)         {            q[i].u=read();q[i].v=read();q[i].a=read();q[i].b=read();q[i].id=i;            if (po[q[i].u].dfs>po[q[i].v].dfs) swap(q[i].u,q[i].v);        }    sort(q+1,q+m+1);    int T=LCA(q[1].u,q[1].v);    work(q[1].u,q[1].v); reserv(T); an[q[1].id]=ans;    if (p[q[1].a] && p[q[1].b] && q[1].a!=q[1].b) an[q[1].id]--;    reserv(T);     for (int i=2; i<=m; i++)        {            work(q[i-1].u,q[i].u);            work(q[i-1].v,q[i].v);            T=LCA(q[i].u,q[i].v);            reserv(T); an[q[i].id]=ans;            if(p[q[i].a] && p[q[i].b] && q[i].a!=q[i].b) an[q[i].id]--;            reserv(T);        }    for (int i=1; i<=m; i++) printf("%d\n",an[i]);    return 0;}

【BZOJ-3757】蘋果樹 塊狀樹 + 樹上莫隊

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.