2325: [ZJOI2011]道館之戰

來源:互聯網
上載者:User

標籤:des   style   blog   http   width   資料   

2325: [ZJOI2011]道館之戰Time Limit: 40 Sec  Memory Limit: 256 MB
Submit: 813  Solved: 309
[Submit][Status]Description

口袋妖怪(又名神奇寶貝或寵物小精靈)紅/藍/綠寶石中的水系道館需要經過三個冰地才能到達館主的面前,冰地中的每一個冰塊都只能經過一次。當一個冰地上的所有冰塊都被經過之後,到下一個冰地的樓梯才會被開啟。

三個冰地分別如下:

 

當走出第三個冰地之後,就可以與館主進行道館戰了。

館主發現這個難度太小,導致經常有挑戰者能通過,為了加大難度,將道館分成了n個房間,每個房間中是兩個冰塊或障礙,表示一列冰地。任意兩個房間之間均有且僅有一條路徑相連,即這n個房間構成一個樹狀結構。

每個房間分成了A和B兩個地區,每一地區都是一個薄冰塊或者障礙物。每次只能移動到相鄰房間的同一類地區(即若你現在在這個房間的A地區,那麼你只能移動到相鄰房間的A地區)或這個房間的另一地區。

現在挑戰者從房間u出發,館主在房間v,那麼挑戰者只能朝接近館主所在房間的方向過去。一開始挑戰者可以在房間u的任意一個冰塊地區內。如果挑戰者踩過的冰塊數達到了最大值(即沒有一種方案踩過的冰塊數更多了),那麼當挑戰者走到最後一個冰塊上時,他會被瞬間傳送到館主面前與館主進行道館戰。

自從館主修改規則後已經經過了m天,每天要麼是有一個挑戰者來進行挑戰,要麼就是館主將某個房間進行了修改。對於每個來的挑戰者,你需要計算出他若要和館主進行戰鬥需要經過的冰塊數。

 

Input

第一行包含兩個正整數n和m。

第2行到第n行,每行包含兩個正整數x和y,表示一條串連房間x和房間y的邊。房間編號為1…n。

接下來n行,每行包含兩個字元。第n + k行表示房間k的兩個地區,第一個字元為A地區,第二個字元為B地區。其中“.”(ASCII碼為46)表示是薄冰塊,“#”(ASCII碼為35)表示是障礙物。

最後的m行,每行一個操作:

l C u s:將房間u裡的兩個地區修改為s。

l Q u v:詢問挑戰者在房間u,館主在房間v時,挑戰者能與館主進行挑戰需要踩的冰塊數。如果房間u的兩個地區都是障礙物,那麼輸出0。

Output

 包含若干行,每行一個整數。即對於輸入中的每個詢問,依次輸出一個答案。

Sample Input5 3

1 2

2 3

2 4

1 5

.#

..

#.

.#

..

Q 5 3

C 1 ##

Q 4 5

Sample Output6

3

HINT

【範例說明】


第一個詢問,從房間5出發經過的冰塊數最多的路徑為:

第二個詢問,從房間4出發經過的冰塊數最多的路徑為:


【資料規模】




 N≤ 30 000



M ≤ 80 000



Source

Day2

 

題目描述太蛋疼了……

總結一下就是一棵樹上,每個點有a,b兩個值,空地或者障礙,障礙就不能通過,同一個節點中a可以到b,但是a是障礙或者b是障礙就不行

詢問從x到y,x從(a,b)兩個點其中一個出發,最多能走多少個空地。即不要求能到達y,只求最多能走多少步

看了人家的題解,x[0..1][0..1]表示從左邊的 左/右上方到 右邊的 左/右上方 最多走多少步,即要求必須到達要走多少步

l[0..1]表示從左邊 左/右上方出發能走多少步,r[0..1]同理

看update函數吧,不是特別麻煩,但是要注意細節

另外在樹鏈剖分算答案的時候,由於你每條線段都是由根往下的

但x到y,從x到lca的路徑是從下往上,lca到y的路徑是從上往下,

也就是說求出的x到lca的路徑,要反向!!!!!

媽的我只swap了l[0],r[0]和l[1]和r[1]

媽的還要swap x[0][1] 和x[1][0]啊啊啊啊啊啊!!!!調了一個半小時艸

/*Author:wuhuajun*/#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#define lson l, mid, rt << 1#define rson mid+1, r, rt << 1 | 1using namespace std; typedef long long ll;typedef double dd;const int maxn=100010, INF = 1000000007; int edge, n, fa[maxn], sz[maxn], son[maxn], dep[maxn], hash[maxn], top[maxn];int h[maxn], num, a[maxn], x, y, tx, ty, Q, b[maxn];char s[22], s1[22], s2[22]; struct Edge{    int to, ne;} e[maxn * 2]; struct Seg{    int x[2][2], l[2], r[2];    void clear()    {        x[0][0] = x[0][1] = x[1][0] = x[1][1] = 0;        l[0] = l[1] = r[0] = r[1] = 0;    }} seg[maxn << 2], ans, c, L, R, ret; void close(){    exit(0);} void addedge(int x,int y){    e[edge].to = y;    e[edge].ne = h[x];    h[x] = edge++;} void dfs(int k,int from){    sz[k] = 1;    son[k] = 0;    dep[k] = dep[from] + 1;    for (int p=h[k];p!=-1;p=e[p].ne)    {        int to = e[p].to;        if (from == to) continue;        fa[to] = k;        dfs(to, k);        sz[k] += sz[to];        if (sz[to] > sz[son[k]]) son[k] = to;    }} void build(int k,int from){    hash[k] = ++num;    top[k] = from;    if (son[k]) build(son[k], from);    for (int p=h[k];p!=-1;p=e[p].ne)    {        int to = e[p].to;        if (to != fa[k] && to != son[k])            build(to, to);    }} //{{{Segment部分 int cal(int x,int y){    return max(-INF, max(x, y));} Seg operator + (Seg a,Seg b){    if (a.x[0][0] == 0 && a.x[0][1] == 0 && a.x[1][0] == 0 && a.x[1][1] == 0 && a.l[0] == 0 && a.l[1] == 0 && a.r[0] == 0 && a.r[1] == 0)        return b;    if (b.x[0][0] == 0 && b.x[0][1] == 0 && b.x[1][0] == 0 && b.x[1][1] == 0 && b.l[0] == 0 && b.l[1] == 0 && b.r[0] == 0 && b.r[1] == 0)        return a;    c.x[0][0] = cal(a.x[0][0] + b.x[0][0], a.x[0][1] + b.x[1][0]);    c.x[0][1] = cal(a.x[0][0] + b.x[0][1], a.x[0][1] + b.x[1][1]);    c.x[1][0] = cal(a.x[1][0] + b.x[0][0], a.x[1][1] + b.x[1][0]);    c.x[1][1] = cal(a.x[1][0] + b.x[0][1], a.x[1][1] + b.x[1][1]);    c.l[0] = max(a.l[0], max(a.x[0][0] + b.l[0], a.x[0][1] + b.l[1]));    c.l[1] = max(a.l[1], max(a.x[1][0] + b.l[0], a.x[1][1] + b.l[1]));    c.r[0] = max(b.r[0], max(b.x[0][0] + a.r[0], b.x[1][0] + a.r[1]));    c.r[1] = max(b.r[1], max(b.x[0][1] + a.r[0], b.x[1][1] + a.r[1]));    return c;} void change(int L,int R,int val1,int val2,int l,int r,int rt){    if (L <= l && r <= R)    {        seg[rt].x[0][0] = seg[rt].l[0] = seg[rt].r[0] = val1;        seg[rt].x[1][1] = seg[rt].l[1] = seg[rt].r[1] = val2;        if (val1 == 1 && val2 == 1)        {            seg[rt].l[0] = seg[rt].l[1] = seg[rt].r[0] = seg[rt].r[1] = 2;            seg[rt].x[0][1] = seg[rt].x[1][0] = 2;        }        else        {            seg[rt].x[0][1] = seg[rt].x[1][0] = -INF;        }        seg[rt].l[0] = max(seg[rt].l[0], 0);        seg[rt].l[1] = max(seg[rt].l[1], 0);        seg[rt].r[0] = max(seg[rt].r[0], 0);        seg[rt].r[1] = max(seg[rt].r[1], 0);        return;    }    int mid = (l + r) >> 1;    if (L <= mid)        change(L,R,val1,val2,lson);    if (mid + 1 <= R)        change(L,R,val1,val2,rson);    seg[rt] = seg[rt << 1] + seg[rt << 1 | 1];} Seg query(int L,int R,int l,int r,int rt){    if (L <= l && r <= R)    {        return seg[rt];    }    int mid = (l + r) >> 1;    Seg ans;    ans.clear();    if (L <= mid)        ans = ans + query(L,R,lson);    if (mid + 1 <= R)        ans = ans + query(L,R,rson);    return ans;}//}}} Seg get_ans(){    tx = top[x];    ty = top[y];    L.clear();    R.clear();    while (tx != ty)    {        if (dep[tx] < dep[ty])        {            R = query(hash[ty], hash[y], 1, n, 1) + R;            y = fa[ty];            ty = top[y];        }        else        {            L = query(hash[tx], hash[x], 1, n, 1) + L;            x = fa[tx];            tx = top[x];        }    }    if (dep[x] < dep[y])    {        R = query(hash[x], hash[y], 1, n, 1) + R;    }    else    {        L = query(hash[y], hash[x], 1, n, 1) + L;    }    swap(L.x[0][1], L.x[1][0]);    swap(L.l[0], L.r[0]);    swap(L.l[1], L.r[1]);    return L + R;} void init(){    scanf("%d %d",&n,&Q);    memset(h,-1,sizeof(h));    for (int i=1;i<=n-1;i++)    {        scanf("%d %d",&x, &y);        addedge(x, y);        addedge(y, x);    }    for (int i=1;i<=n;i++)    {        scanf("%s", s1);        a[i] = s1[0] == ‘.‘ ? 1 : -INF;        b[i] = s1[1] == ‘.‘ ? 1 : -INF;    }    dfs(1, 0);    build(1, 1);    /*    for (int i=1;i<=n;i++)    {        printf("i:%d top:%d hash:%d\n",i, top[i], hash[i]);    }    */    for (int i=1;i<=n;i++)        change(hash[i], hash[i], a[i], b[i], 1, n, 1);    while (Q--)    {        scanf("%s", s);        if (s[0] == ‘Q‘)        {            scanf("%d %d",&x, &y);            ret = get_ans();            printf("%d\n", max(ret.l[0], ret.l[1]));        }        else        {            scanf("%d",&x);            scanf("%s", s1);            int t1 = s1[0] == ‘.‘ ? 1 : -INF;            int t2 = s1[1] == ‘.‘ ? 1 : -INF;            change(hash[x], hash[x], t1, t2, 1, n, 1);        }    }} int main (){    init();    close();    return 0;}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.