• 数链剖分(Housewife Wind )


     题目链接:https://vjudge.net/contest/279350#problem/B

    题目大意:给你n,q,s。n指的是有n个点,q代表有q次询问,s代表的是起点。然后接下来会有n-1条边,双向边,带有权值,对于q次询问,如果输入的第一个数是1,然后接下来会输入两个数,t1,t2。t带边将第t1条边的权值改成t2.如果第一个数是0,接下来会输入一个t,询问从s到t的花费。

    具体思路:对于边权,我们可以改成点权,这条边的权值赋给这条边上深度大的那条边,然后就是单点更新和区间查询了。

    AC代码:

      1 #include<iostream>
      2 #include<cmath>
      3 #include<stack>
      4 #include<queue>
      5 #include<stdio.h>
      6 #include<string>
      7 #include<cstring>
      8 #include<algorithm>
      9 using namespace std;
     10 # define inf 0x3f3f3f3f
     11 # define ll long long
     12 # define lson l,m,rt<<1
     13 # define rson m+1,r,rt<<1|1
     14 const int maxn = 1e5+100;
     15 int sto[maxn],head[maxn],edgnum,dfsnum,depth[maxn];
     16 int son[maxn],father[maxn],Size[maxn],ord[maxn],cost[maxn],top[maxn];
     17 int tree[maxn<<2];
     18 struct node
     19 {
     20     int fr;
     21     int to;
     22     int nex;
     23     int cost;
     24 } edge[maxn<<2],po[maxn<<2];
     25 void addedge(int fr,int to)
     26 {
     27     edge[edgnum].fr=fr;
     28     edge[edgnum].to=to;
     29     edge[edgnum].nex=head[fr];
     30     head[fr]=edgnum++;
     31 }
     32 void dfs1(int fr,int rt,int dep)
     33 {
     34     father[fr]=rt;
     35     Size[fr]=1;
     36     son[fr]=-1;
     37     depth[fr]=dep;
     38     for(int i=head[fr]; i!=-1; i=edge[i].nex)
     39     {
     40         int to=edge[i].to;
     41         if(to==rt)
     42             continue;
     43         dfs1(to,fr,dep+1);
     44         Size[fr]+=Size[to];
     45         if(son[to]==-1||(Size[son[fr]]<Size[to]))
     46         {
     47             son[fr]=to;
     48         }
     49     }
     50 }
     51 void dfs2(int fr,int rt)
     52 {
     53     ord[fr]=++dfsnum;
     54     cost[ord[fr]]=sto[fr];
     55     top[fr]=rt;
     56     if(son[fr]!=-1)
     57         dfs2(son[fr],rt);
     58     for(int i=head[fr]; i!=-1; i=edge[i].nex)
     59     {
     60         int u=edge[i].to;
     61         if(son[fr]!=u&&father[fr]!=u)
     62         {
     63             dfs2(u,u);
     64         }
     65     }
     66 }
     67 void up(int rt)
     68 {
     69     tree[rt]=tree[rt<<1]+tree[rt<<1|1];
     70 }
     71 void buildtree(int l,int r,int rt)
     72 {
     73     if(l==r)
     74     {
     75         tree[rt]=sto[l];
     76         return ;
     77     }
     78     int m=(l+r)>>1;
     79     buildtree(lson);
     80     buildtree(rson);
     81     up(rt);
     82 }
     83 int query(int l,int r,int rt,int L,int R)
     84 {
     85     if(L<=l&&R>=r)
     86     {
     87         return tree[rt];
     88     }
     89     int ans=0;
     90     int m=(l+r)>>1;
     91     if(L<=m)
     92         ans+=query(lson,L,R);
     93     if(R>m)
     94         ans+=query(rson,L,R);
     95     up(rt);
     96     return ans;
     97 }
     98 void update(int l,int r,int rt,int pos,int p)
     99 {
    100     if(l==r)
    101     {
    102         tree[rt]=p;
    103         return ;
    104     }
    105     int m=(l+r)>>1;
    106     if(pos<=m)
    107         update(lson,pos,p);
    108     if(pos>m)
    109         update(rson,pos,p);
    110     up(rt);
    111 }
    112 int Query(int n,int x,int y)
    113 {
    114     int tx=top[x],ty=top[y];
    115     int ans=0;
    116     while(tx!=ty)
    117     {
    118         if(depth[tx]<depth[ty])
    119         {
    120             swap(tx,ty);
    121             swap(x,y);
    122         }
    123         ans+=query(1,n,1,ord[tx],ord[x]);
    124         x=father[tx],tx=top[x];
    125     }
    126     if(depth[x]<depth[y])
    127     {
    128         swap(x,y);
    129     }
    130     return ans+query(1,n,1,ord[y]+1,ord[x]);//这个地方注意应该是ord[y]+1,如果我们询问的是从3->5的,有可能3这个点是另一条边的权值,所以应该把点往下移动一个。
    131 }
    132 int main()
    133 {
    134     int n,q,s;
    135     scanf("%d %d %d",&n,&q,&s);
    136     int t1,t2,t3;
    137     memset(head,-1,sizeof(head));
    138     for(int i=1; i<=n-1; i++)
    139     {
    140         scanf("%d %d %d",&t1,&t2,&t3);
    141         addedge(t1,t2);
    142         addedge(t2,t1);
    143         po[i].fr=t1;
    144         po[i].to=t2;
    145         po[i].cost=t3;
    146     }
    147     dfs1(1,-1,1);
    148     dfs2(1,1);
    149     for(int i=1; i<=n-1; i++)
    150     {
    151         t1=depth[po[i].fr];
    152         t2=depth[po[i].to];
    153         if(t1>t2)
    154         {
    155             swap(po[i].fr,po[i].to);
    156         }
    157         update(1,n,1,ord[po[i].to],po[i].cost);
    158     }
    159     while(q--)
    160     {
    161 
    162         scanf("%d",&t1);
    163         if(t1==0)
    164         {
    165             scanf("%d",&t2);
    166             int ans=Query(n,s,t2);
    167             printf("%d
    ",ans);
    168             s=t2;
    169         }
    170         else
    171         {
    172             scanf("%d %d",&t1,&t2);
    173             update(1,n,1,ord[po[t1].to],t2);
    174         }
    175     }
    176     return 0;
    177 }

     

  • 相关阅读:
    C# Array.CreateInstance创建二维数组及如何遍历二维数组
    Camstar开发常用数据库表及其关联
    Camstar开发C#代码规范、Camstar更新以及Designer 开发规范
    Andorid存储方式---读写文件
    Andorid存储方式----SharedPreferences存储
    InputStream类只能读取一次
    ssh文件上传问题
    关于html自定义属性
    我是程序猿,我爱做菜。
    第8章 Spring Web Flow
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10285816.html
Copyright © 2020-2023  润新知