zoukankan      html  css  js  c++  java
  • POJ 2763 Housewife Wind

    题目链接:传送门

    题目大意:给你一棵树,小明起点在一个节点上,然后每条边有权值,有两种操作。

         0 X叫小明从当前节点到 X,花费为路径上权值和。

         1 X V 表示把 按输入顺序中第 X 条边的权值变为 V

         对于每个操作 0,输出对应的花费。

    题目思路:树链剖分

         对于这种边上有权值但是是查找点对的题目,可以把边上的权值相应的赋值给对

         应的深度较深的节点。查找时最后一次的操作需要把 id[x]+1,因为此时id[x]

         对应的边不用经过。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cmath>
      5 #include <algorithm>
      6 #include <cstring>
      7 #include <stack>
      8 #include <cctype>
      9 #include <queue>
     10 #include <string>
     11 #include <vector>
     12 #include <set>
     13 #include <map>
     14 #include <climits>
     15 #define lson rt<<1,l,mid
     16 #define rson rt<<1|1,mid+1,r
     17 #define fi first
     18 #define se second
     19 #define ping(x,y) ((x-y)*(x-y))
     20 #define mst(x,y) memset(x,y,sizeof(x))
     21 #define mcp(x,y) memcpy(x,y,sizeof(y))
     22 using namespace std;
     23 #define gamma 0.5772156649015328606065120
     24 #define MOD 1000000007
     25 #define inf 0x3f3f3f3f
     26 #define N 100001
     27 #define maxn 30010
     28 typedef pair<int,int> PII;
     29 typedef long long LL;
     30 LL read(){
     31     LL x=0,f=1;char ch=getchar();
     32     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     33     while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
     34     return x*f;
     35 }
     36 
     37 int n,m,k,L,R,S;
     38 int seg[N<<2];
     39 int head[N],hcnt;
     40 int fa[N];
     41 int son[N];
     42 int siz[N];
     43 int dep[N];
     44 int top[N];
     45 int id[N],tid;
     46 int posi[N];
     47 struct Node{int to,nxt;}node[N<<1];
     48 struct Edge{int x,y,v;}edge[N<<1];
     49 
     50 void init(){
     51     mst(id,0);mst(siz,0);mst(son,0);
     52     mst(head,-1);hcnt=tid=0;
     53 }
     54 void dfs1(int u,int f,int deep){
     55     dep[u]=deep;
     56     fa[u]=f;
     57     siz[u]=1;
     58     for(int i=head[u];~i;i=node[i].nxt){
     59         int e=node[i].to;
     60         if(e==f)continue;
     61         dfs1(e,u,deep+1);
     62         siz[u]+=siz[e];
     63         if(!son[u]||siz[son[u]]<siz[e])
     64             son[u]=e;
     65     }
     66 }
     67 void dfs2(int u,int tp){
     68     top[u]=tp;
     69     id[u]=++tid;
     70     posi[tid]=u;
     71     if(!son[u])return;
     72     dfs2(son[u],tp);
     73     for(int i=head[u];~i;i=node[i].nxt){
     74         int e=node[i].to;
     75         if(!id[e])dfs2(e,e);
     76     }
     77 }
     78 void update(int rt,int l,int r,int v){
     79     if(l==r){seg[rt]=v;return;}
     80     int mid=l+r>>1;
     81     if(L<=mid)update(lson,v);
     82     else update(rson,v);
     83     seg[rt]=seg[rt<<1]+seg[rt<<1|1];
     84 }
     85 int query(int rt,int l,int r){
     86     if(L<=l&&r<=R)return seg[rt];
     87     int mid=l+r>>1;
     88     int temp=0;
     89     if(L<=mid)temp+=query(lson);
     90     if(R>mid)temp+=query(rson);
     91     return temp;
     92 }
     93 int lca(int x,int y){
     94     int res=0;
     95     while(top[x]!=top[y]){
     96         if(dep[top[x]]<dep[top[y]])swap(x,y);
     97         L=id[top[x]],R=id[x];
     98         res+=query(1,1,n);
     99         x=fa[top[x]];
    100     }
    101     if(dep[x]>dep[y])swap(x,y);
    102     L=id[x]+1,R=id[y];
    103     res+=query(1,1,n);
    104     return res;
    105 }
    106 inline void addedge(int x,int y,int v){
    107     node[hcnt].to=y,node[hcnt].nxt=head[x],head[x]=hcnt++;
    108     node[hcnt].to=x,node[hcnt].nxt=head[y],head[y]=hcnt++;
    109 }
    110 int main(){
    111     int i,j,group,x,y,v,Case=0;
    112     while(scanf("%d",&n)!=EOF){
    113         init();
    114         m=read();S=read();
    115         for(i=1;i<n;++i){
    116             edge[i].x=read();edge[i].y=read();edge[i].v=read();
    117             addedge(edge[i].x,edge[i].y,edge[i].v);
    118         }
    119         dfs1(1,1,1);dfs2(1,1);
    120         mst(seg,0);
    121         for(i=1;i<n;++i){
    122             if(dep[edge[i].x]<dep[edge[i].y])swap(edge[i].x,edge[i].y);
    123             L=id[edge[i].x];
    124             update(1,1,n,edge[i].v);
    125         }
    126         while(m--){
    127             y=read();x=read();
    128             if(y==0){
    129                 printf("%d
    ",lca(S,x));
    130                 S=x;
    131             }
    132             else{
    133                 v=read();
    134                 L=id[edge[x].x];
    135                 update(1,1,n,v);
    136             }
    137         }
    138     }
    139     return 0;
    140 }
  • 相关阅读:
    Ubuntu10下MySQL搭建Amoeba_分片
    MySQL多Text字段报8126错误(解决过程)
    SQL Server 维护计划实现数据库备份(Step by Step)
    Ubuntu10下MySQL搭建Master Slave
    Ubuntu10下安装JAVA JDK
    Windows下安装MySQL最佳实践
    Ubuntu12下重新挂载硬盘
    Windows 下使用Git管理Github项目
    解决Windows Server2008 R2中IE开网页时弹出阻止框
    Win Server 2008中开启Areo特效
  • 原文地址:https://www.cnblogs.com/Kurokey/p/5899070.html
Copyright © 2011-2022 走看看