• QTREEⅠ SPOJ


    树剖模板,注意把边化为点后要查到y的儿子。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int N=25000;
      4 int f[N],bel[N],w[N],id[N],pos[N],d[N],size[N],son[N],head[N];
      5 int n,idx,cnt,num,T,rt;
      6 struct node
      7 {
      8     int l,r,s,mx;
      9     void clean()
     10     {
     11         l=r=s=mx=-1e9;
     12     }
     13 }t[N<<2];
     14 struct edge
     15 {
     16     int to,nex,w,x;
     17 }e[N<<1],a[N];
     18 void add(int x,int y,int w)
     19 {
     20     e[++cnt].to=y;e[cnt].nex=head[x];head[x]=cnt;e[cnt].x=x;
     21 }
     22 void dfs1(int x,int fa)
     23 {
     24     size[x]=1;
     25     for(int i=head[x];i;i=e[i].nex)
     26     {
     27         int y=e[i].to;
     28         if(y==fa)continue;
     29         f[y]=x;d[y]=d[x]+1;
     30         dfs1(y,x);
     31         if(size[y]>size[son[x]])son[x]=y;
     32         size[x]+=size[y];
     33     }
     34     return;
     35 }
     36 void dfs2(int x,int chain)
     37 {
     38     bel[x]=chain;pos[x]=++idx;id[idx]=x;
     39     if(son[x])dfs2(son[x],chain);
     40     for(int i=head[x];i;i=e[i].nex)
     41     {
     42         int y=e[i].to;
     43         if(y==f[x]||y==son[x])continue;
     44         dfs2(y,y);
     45     }
     46 }
     47 void build(int &x,int l,int r)
     48 {
     49     x=++num;
     50     if(l==r){
     51         t[x].s=t[x].mx=w[l];return;
     52     }
     53     int mid=l+r>>1;
     54     build(t[x].l,l,mid);build(t[x].r,mid+1,r);
     55     t[x].mx=max(t[t[x].l].mx,t[t[x].r].mx);
     56     return; 
     57 }
     58 int query(int x,int l,int r,int L,int R)
     59 {
     60     if(l==L&&r==R)return t[x].mx;
     61     int mid=l+r>>1;
     62     if(R<=mid)return query(t[x].l,l,mid,L,R);
     63     else if(L>mid)return query(t[x].r,mid+1,r,L,R);
     64     else return max(query(t[x].l,l,mid,L,mid),query(t[x].r,mid+1,r,mid+1,R)); 
     65 }
     66 void change(int x,int l,int r,int pos,int ww)
     67 {
     68     if(l==r){t[x].s=t[x].mx=ww;return;}
     69     int mid=l+r>>1;
     70     if(pos<=mid)change(t[x].l,l,mid,pos,ww);
     71     else change(t[x].r,mid+1,r,pos,ww);
     72     t[x].mx=max(t[t[x].l].mx,t[t[x].r].mx);
     73 }
     74 int querytree(int x,int y)
     75 {
     76     int ans=-1e9;
     77     while(bel[x]!=bel[y])
     78     {
     79         if(d[bel[x]]<d[bel[y]])swap(x,y);
     80         ans=max(ans,query(rt,1,n,pos[bel[x]],pos[x]));
     81         x=f[bel[x]];
     82     }
     83     if(d[x]<d[y])swap(x,y);
     84     if(d[son[y]]<=d[x])
     85     ans=max(ans,query(rt,1,n,pos[son[y]],pos[x]));
     86     return ans;
     87 }
     88 void init()
     89 {
     90     memset(f,0,sizeof(f));
     91     memset(d,0,sizeof(d));
     92     memset(size,0,sizeof(size));
     93     memset(son,0,sizeof(son));
     94     memset(bel,0,sizeof(bel));
     95     memset(pos,0,sizeof(pos));
     96     memset(head,0,sizeof(head));
     97     memset(id,0,sizeof(id));
     98     memset(w,0,sizeof(w));cnt=idx=num=0;rt=0;
     99     for(int i=1;i<=num;++i)t[i].clean();
    100 }
    101 int main()
    102 {
    103     scanf("%d",&T);
    104     while(T--)
    105     {
    106         init();int x,y,ww;
    107         scanf("%d",&n);
    108         for(int i=1;i<n;++i)
    109         {
    110             scanf("%d%d%d",&x,&y,&ww);
    111             add(x,y,ww);add(y,x,ww);
    112             a[i].x=x;a[i].to=y;a[i].w=ww;
    113         }
    114         dfs1(1,1);dfs2(1,1);
    115         build(rt,1,n);char s[10];
    116         for(int i=1;i<n;i++)
    117         {
    118             x=d[a[i].x]>d[a[i].to]?a[i].x:a[i].to;
    119             change(rt,1,n,pos[x],a[i].w);
    120         }
    121         change(rt,1,n,pos[1],-1e9);
    122         while(1)
    123         {
    124             scanf("%s",s);
    125             if(s[0]=='D')break;
    126             if(s[0]=='Q')
    127             {
    128                 scanf("%d%d",&x,&y);
    129                 printf("%d
    ",querytree(x,y));
    130             }
    131             else
    132             {
    133                 scanf("%d%d",&x,&y);
    134                 x=d[a[x].x]>d[a[x].to]?a[x].x:a[x].to;
    135                 change(rt,1,n,pos[x],y);
    136             }
    137         }
    138     }
    139     return 0;
    140 }
  • 相关阅读:
    进程间的通信如何实现?
    试解释操作系统原理中的作业、进程、线程、管程各自的定义。
    字符数组和strcpy
    字符串转化成整数
    整数字符串转化
    海量数据/日志检索问题
    哈夫曼编码问题
    Trie树,又称单词查找树、字典
    初识面向对象
    序列化 json pickle shelve configparser
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8342507.html
Copyright © 2020-2023  润新知