【COGS1672】【SPOJ375】QTREE,cogs1672spoj375

來源:互聯網
上載者:User

【COGS1672】【SPOJ375】QTREE,cogs1672spoj375

這是我的第一個邊權鏈剖
COGS上和SPOJ有點不一樣就是沒有多組資料了本質還是一樣的
我寫的是COGS那個其實改一改就可以去SPOJ AC了= -=
(可是我現在上不去SPOJ臥槽(╯‵□′)╯︵┻━┻)
【題目描述】

一天機房的夜晚,無數人在MC裡奮鬥著。。。

大家都知道礦產對於MC來說是多麼的重要,但由於礦越挖越少,勇士們不得不跑到更遠的地方挖礦,但這樣路途上就會花費相當大的時間,導致挖礦效率低下。

cjj提議修一條鐵路,大家一致同意。

大家都被CH分配了一些任務:

zjmfrank2012負責繪製出一個礦道地圖,這個地圖包括家(當然這也是一個礦,畢竟不把家掏空我們是不會走的),和無數個礦,所以大家應該可以想出這是一個無向無環圖,也就是一棵樹。

Digital_T和cstdio負責鋪鐵路。。所以這裡沒他們什麼事,兩位可以勞作去了。

這個時候song526210932和RMB突然發現有的礦道會刷怪,並且怪的數量會發生變化。作為採礦主力,他們想知道從一個礦到另一個礦的路上哪一段會最困難。。。(困難值用zjm的死亡次數表示)。
【輸入格式】

輸入檔案的第一行有一個整數N,代表礦的數量。礦的編號是1到N。

接下來N-1行每行有三個整數a,b,c,代表第i號礦和第j號礦之間有一條路,在初始時這條路的困難值為c。

接下來有若干行,每行是“CHANGE i ti”或者“QUERY a b”,前者代表把第i條路(路按所給順序從1到M編號)的困難值修改為ti,後者代表查詢a到b所經過的道路中的最大困難值。

輸入資料以一行“DONE”結束。
【輸出格式】

對每個“QUERY”操作,輸出一行一個正整數,即最大困難值。
【範例輸入】

3

1 2 1

2 3 2

QUERY 1 2

CHANGE 1 3

QUERY 1 2

DONE
【範例輸出】

1

3
【提示】

對於60%的資料,1≤N≤50

對於100%的資料,1≤N≤10000,1≤c≤1000000,1≤操作次數≤100000
【來源】

由GDFRWMY 改編自SPOJ 375 QTREE

資料by cstdio

邊權鏈剖略蛋疼
我用每條邊兩個端點裡深度比較大的那個以點權繼承這條邊的邊權
最後在Query_max函數在樹的統計Count基礎上稍微改了改就行了
(直接暴力用LCA會出傻逼的錯誤我一開始竟然沒注意到多虧zky學長提醒QUQ)

//AC code by CreationAugust#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define MAXINT 0x7fffffff#define MAXN 100010#define lchild rt<<1,l,mid#define rchild rt<<1|1,mid+1,r#define ln rt<<1#define rn rt<<1|1using namespace std;int w;int val[MAXN];int size[MAXN],deep[MAXN],chain[MAXN],num[MAXN],fa[MAXN][18];bool vis[MAXN];int top,tp;int a,b;int u,v;int n,T;int x[MAXN],y[MAXN],z[MAXN];char ch[6];struct edge{    edge *next;    int val;    int to;}*prev[MAXN],e[MAXN*2];struct seg{    int maxn;    int l;    int r;}tree[MAXN*4];inline void insert(int u,int v,int w){    e[++top].to=v;    e[top].val=w;    e[top].next=prev[u];    prev[u]=&e[top];}inline void dfs1(int x){    size[x]=1;    vis[x]=1;    for (int i=1;i<=17;i++)    {        if (deep[x]<(1<<i)) break;        fa[x][i]=fa[fa[x][i-1]][i-1];    }    for (edge *i=prev[x];i;i=i->next)    {        int t=i->to;        if (vis[t]) continue;        deep[t]=deep[x]+1;        fa[t][0]=x;        dfs1(t);        size[x]+=size[t];    }}inline void dfs2(int x,int last){    chain[x]=last;    num[x]=++tp;    int t=0;    for (edge *i=prev[x];i;i=i->next)         if (deep[i->to]>deep[x]&&size[t]<size[i->to])              t=i->to;    if (!t) return;    dfs2(t,last);    for (edge *i=prev[x];i;i=i->next)        if (deep[i->to]>deep[x]&&i->to!=t)            dfs2(i->to,i->to);}inline void push_up(int rt){    tree[rt].maxn=max(tree[ln].maxn,tree[rn].maxn);}inline void build(int rt=1,int l=1,int r=n){    tree[rt].l=l;    tree[rt].r=r;    if (l==r) return;    int mid=(l+r)>>1;    build(lchild);    build(rchild);}inline int lca(int a,int b){    if (deep[a]<deep[b]) swap(a,b);    int t=deep[a]-deep[b];    for (int i=0;i<=17;i++)        if (t&(1<<i)) a=fa[a][i];    for (int i=17;i>=0;i--)        if (fa[a][i]!=fa[b][i])        {            a=fa[a][i];            b=fa[b][i];        }    if (a==b) return a;    else return fa[a][0];}void modify(int rt,int l,int r,int w){    int L=tree[rt].l,R=tree[rt].r,mid=(L+R)>>1;    if (L==l&&r==R)    {        tree[rt].maxn=w;        return;    }    if (l>mid) modify(rn,l,r,w);    else    if (r<=mid) modify(ln,l,r,w);    else    {        modify(lchild,w);        modify(rchild,w);    }    push_up(rt);} void Modify(int a,int b,int w){    while (chain[a]!=chain[b])    {        modify(1,num[chain[a]],num[a],w);        a=fa[chain[a]][0];    }    modify(1,num[b],num[a],w);}inline int query_max(int rt,int l,int r){    int L=tree[rt].l,R=tree[rt].r,mid=(L+R)>>1;    if (L==l&&R==r)    {        return tree[rt].maxn;    }    if (l>mid) return query_max(rn,l,r);    else    if (r<=mid) return query_max(ln,l,r);    else        return max(query_max(lchild),query_max(rchild));}inline int Query_max(int a,int b){    int ret=-MAXINT;    while (chain[a]!=chain[b])    {        ret=max(ret,query_max(1,num[chain[a]],num[a]));        a=fa[chain[a]][0];    }    if (num[b]+1<=num[a])        ret=max(ret,query_max(1,num[b]+1,num[a]));    return ret;}int main(){       freopen("qtree.in","r",stdin);    freopen("qtree.out","w",stdout);        scanf("%d",&n);        for (int i=1;i<n;i++)        {            scanf("%d%d%d",&u,&v,&w);            insert(u,v,w);            insert(v,u,w);            x[i]=u;            y[i]=v;            z[i]=w;        }        dfs1(1);        dfs2(1,1);        build();        for (int i=1;i<n;i++)        {            if (deep[x[i]]<deep[y[i]])                val[y[i]]=z[i];            else                val[x[i]]=z[i];        }        for (int i=1;i<=n;i++)            modify(1,num[i],num[i],val[i]);        while (1)        {            scanf("%s",ch);            if (ch[1]=='H')            {                scanf("%d%d",&a,&b);                if (deep[x[a]]<deep[y[a]])                    modify(1,num[y[a]],num[y[a]],b);                else                    modify(1,num[x[a]],num[x[a]],b);            }            else            if (ch[1]=='U')            {                scanf("%d%d",&a,&b);                int t=lca(a,b);                printf("%d\n",max(Query_max(a,t),Query_max(b,t)));              }            else            if (ch[1]=='O')                break;        }}

聯繫我們

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