poj 3237 加強版 query on a tree 樹鏈剖分

來源:互聯網
上載者:User

連結:

http://www.spoj.pl/problems/QTREE/

http://poj.org/problem?id=3237


題意:一棵樹,兩種更新操作,改變一條邊的邊權,將a ->b路徑上的所有邊權取反,詢問一條路徑上的最大邊權

都是典型的樹鏈剖分,下面一題是上面的加強版,還要在樹上進行成段更新,其實也不難。

只是區間還要再記錄一個最小值,因為取反操作的話會使得區間的最大值和最小值互換。

然後就是樹鏈剖分的老套路,如果是重鏈,線上段樹中更新,否則直接改變邊權。

線段樹中下放懶惰標記的時候寫漏了,調了許久,囧爆了。。。。

好像還可以用動態樹實現吧,概念都看懂了,只是沒實踐過,改天去學了再貼上來吧

下面是這兩題的代碼,My Code有點搓 - -,觀看請謹慎,以免傷了眼*_*

spoj  375  query on a tree

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1const int maxn = 20010;const int inf = ~0u>>2;int M[maxn<<2];struct node{    int s,t,w,next;}edge[maxn*2];int E,n;int size[maxn] , fa[maxn] , heavy[maxn] , head[maxn] , dep[maxn] , rev[maxn] , num[maxn] , cost[maxn];int Seg_size;inline void Max(int &x,int y){if(x<y) x=y;}int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}void add_edge(int s,int t,int w){    edge[E].w=w;    edge[E].s=s;    edge[E].t=t;    edge[E].next=head[s];    head[s]=E++;}void dfs(int u,int f){    int mx=-1,e=-1;    size[u]=1;    for(int i=head[u];i!=-1;i=edge[i].next)    {        int v=edge[i].t;        if(v==f) continue;        dep[v]=dep[u]+1;        rev[v]=i^1;        dfs(v,u);        size[u]+=size[v];        if(size[v]>mx)        {            mx=size[v];            e=i;        }    }    heavy[u]=e;    if(e!=-1)  fa[edge[e].t]=u;}inline void pushup(int rt){    M[rt]=max(M[rt<<1],M[rt<<1|1]);}void build(int l,int r,int rt){    M[rt]=inf;    if(l==r){        return ;    }    int m=(l+r)>>1;    build(lson);    build(rson);}void update(int p,int val,int l,int r,int rt){    if(l==r){       M[rt]=val;       return ;    }    int m=(l+r)>>1;    if(p<=m) update(p,val,lson);    else update(p,val,rson);    pushup(rt);}int query(int L,int R,int l,int r,int rt){    if(L<=l&&r<=R){        return M[rt];    }    int m=(l+r)>>1;    int ret=0;    if(L<=m) ret=max(ret,query(L,R,lson));    if(R>m) ret=max(ret,query(L,R,rson));    return ret;}void prepare(){    build(1,n-1,1);    memset(num,-1,sizeof(num));    dep[0]=0;Seg_size=0;    for(int i=0;i<n;i++) fa[i]=i;    dfs(0,0);        for(int i=0;i<n;i++)    {        if(heavy[i]==-1)        {            int pos=i;            while(pos && edge[heavy[edge[rev[pos]].t]].t == pos)            {                int t=rev[pos];                num[t]=num[t^1]=++Seg_size;                update(Seg_size,edge[t].w,1,n-1,1);                pos=edge[t].t;            }        }    }}void change(int edge_id,int val){    if(num[edge_id]==-1) edge[edge_id].w=edge[edge_id^1].w=val;    else update(num[edge_id],val,1,n-1,1);}int calc(int u,int lca){    int ans=-inf;int vi=0;    while(u!=lca)    {        vi++;        if(vi==10) break;        int r=rev[u];        if(num[r]==-1) Max(ans,edge[r].w),u=edge[r].t;        else         {            int p=fa[u];            if(dep[p] < dep[lca]) p=lca;            int l=num[r];            int r=num[heavy[p]];            Max(ans,query(l,r,1,n-1,1));            u=p;        }    }    return ans;}int lca(int u,int v){    while(1)    {        int a=find(u),b=find(v);        if(a==b) return dep[u] < dep[v] ? u : v;//a,b在同一條重鏈上        else if(dep[a]>=dep[b]) u=edge[rev[a]].t;        else v=edge[rev[b]].t;    }}int solve(int u,int v){    int p=lca(u,v);    return max(calc(u,p),calc(v,p));}int main(){    int t,i,a,b,c;    scanf("%d",&t);    while(t--)    {        memset(head,-1,sizeof(head));        E=0;        scanf("%d",&n);        for(i=0;i<n-1;i++)        {            scanf("%d%d%d",&a,&b,&c);a--;b--;            add_edge(a,b,c);            add_edge(b,a,c);        }        prepare();        char op[20];        while(scanf("%s",op)!=EOF && strcmp(op,"DONE"))        {            if(op[0]=='C')            {                scanf("%d%d",&a,&c);                change((a-1)*2,c);            }            else             {                scanf("%d%d",&a,&b);                printf("%d\n",solve(a-1,b-1));            }        }    }    return 0;}/*131 2 12 3 2QUERY 1 2CHANGE 1 3QUERY 1 2DONE13171 2 11 3 22 4 32 5 43 6 53 7 6Query 1 7*/


poj 3237

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1const int maxn = 100010;const int inf = ~0u>>2;int M[maxn<<2];int Mi[maxn<<2];int col[maxn<<2];struct node{int s,t,w,next;}edge[maxn*2];int E,n;int size[maxn] , fa[maxn] , heavy[maxn] , head[maxn] , dep[maxn] , rev[maxn] , num[maxn] , cost[maxn];int Seg_size;inline void Max(int &x,int y){if(x<y) x=y;}inline int max(int a,int b){return a>b?a:b;}inline int min(int a,int b){return a>b?b:a;}int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}void add_edge(int s,int t,int w){edge[E].w=w;edge[E].s=s;edge[E].t=t;edge[E].next=head[s];head[s]=E++;}void dfs(int u,int f){int mx=-1,e=-1;size[u]=1;for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].t;if(v==f) continue;dep[v]=dep[u]+1;rev[v]=i^1;dfs(v,u);size[u]+=size[v];if(size[v]>mx){mx=size[v];e=i;}}heavy[u]=e;if(e!=-1)  fa[edge[e].t]=u;}void build(int l,int r,int rt){Mi[rt]=inf;M[rt]=-inf;col[rt]=0;if(l==r){return ;}int m=(l+r)>>1;build(lson);build(rson);}inline void pushup(int rt){M[rt]=max(M[rt<<1],M[rt<<1|1]);Mi[rt]=min(Mi[rt<<1],Mi[rt<<1|1]);}void make(int rt){int tmp=Mi[rt];Mi[rt]=-M[rt];M[rt]=-tmp;}void pushdown(int rt){if(col[rt]){       col[rt<<1]^=1;   make(rt<<1);   col[rt<<1|1]^=1;   make(rt<<1|1);   col[rt]=0;//很久沒寫線段樹,連這個都忘了,囧}}void update(int p,int val,int l,int r,int rt){if(l==r){   Mi[rt]=M[rt]=val;   return ;}pushdown(rt);int m=(l+r)>>1;if(p<=m) update(p,val,lson);else update(p,val,rson);pushup(rt);}void justdoit(int L,int R,int l,int r,int rt){//printf("L=%d R=%d l=%d r=%d\n",L,R,l,r);if(L<=l&&r<=R){col[rt]^=1;make(rt);return ;}pushdown(rt);int m=(l+r)>>1;if(L<=m) justdoit(L,R,lson);if(R>m) justdoit(L,R,rson);pushup(rt);}int query(int L,int R,int l,int r,int rt){if(L<=l&&r<=R){return M[rt];}pushdown(rt);int m=(l+r)>>1;int ret=-inf;if(L<=m) ret=max(ret,query(L,R,lson));if(R>m) ret=max(ret,query(L,R,rson));return ret;}void prepare(){build(1,n-1,1);memset(num,-1,sizeof(num));dep[0]=0;Seg_size=0;for(int i=0;i<n;i++) fa[i]=i;dfs(0,0);for(int i=0;i<n;i++){if(heavy[i]==-1){int pos=i;while(pos && edge[heavy[edge[rev[pos]].t]].t == pos){int t=rev[pos];num[t]=num[t^1]=++Seg_size;update(Seg_size,edge[t].w,1,n-1,1);pos=edge[t].t;}}}}void change(int edge_id,int val){if(num[edge_id]==-1) edge[edge_id].w=edge[edge_id^1].w=val;else update(num[edge_id],val,1,n-1,1);}int calc(int u,int lca){int ans=-inf;    while(u!=lca){int r=rev[u];if(num[r]==-1) Max(ans,edge[r].w),u=edge[r].t;else {int p=fa[u];if(dep[p] < dep[lca]) p=lca;int l=num[r];int r=num[heavy[p]];Max(ans,query(l,r,1,n-1,1));u=p;}}return ans;}void gao(int u,int lca){while(u!=lca){int r=rev[u];if(num[r]==-1) edge[r].w=edge[r^1].w=-edge[r].w,u=edge[r].t;else{int p=fa[u];if(dep[p] < dep[lca]) p=lca;int l=num[r];int r=num[heavy[p]];//printf("l=%d r=%d\n",l,r);justdoit(l,r,1,n-1,1);u=p;}}}int lca(int u,int v){while(1){int a=find(u),b=find(v);if(a==b) return dep[u] < dep[v] ? u : v;//a,b在同一條重鏈上else if(dep[a]>=dep[b]) u=edge[rev[a]].t;else v=edge[rev[b]].t;}}int solve(int u,int v){int p=lca(u,v);return max(calc(u,p),calc(v,p));}void sol(int u,int v){int p=lca(u,v);//printf("p=%d\n",p);gao(u,p);gao(v,p);}int main(){int t,i,a,b,c;scanf("%d",&t);while(t--){memset(head,-1,sizeof(head));E=0;scanf("%d",&n);for(i=0;i<n-1;i++){scanf("%d%d%d",&a,&b,&c);a--;b--;add_edge(a,b,c);add_edge(b,a,c);}prepare();char op[20];while(scanf("%s",op)!=EOF && strcmp(op,"DONE")){if(op[0]=='C'){scanf("%d%d",&a,&c);change((a-1)*2,c);}else if(op[0]=='N'){scanf("%d%d",&a,&b);if(a==b) while(1);sol(a-1,b-1);}else {scanf("%d%d",&a,&b);if(a==b) while(1);printf("%d\n",solve(a-1,b-1));}}}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.