POJ2763 Housewife Wind

树链剖分边更新,线段树单点更新,区间查询

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <cstdlib>
  5 using namespace std;
  6 #define lson l,m,rt<<1
  7 #define rson m+1,r,rt<<1|1
  8 const int maxn = 100005;
  9 int siz[maxn],son[maxn],fa[maxn],dep[maxn],top[maxn],tid[maxn],lable;
 10 int head[maxn],cnt;
 11 struct edge
 12 {
 13     int v,w,en,next;
 14 }e[maxn*2];
 15 int n,m,s;
 16 int sum[maxn<<2];
 17 void init()
 18 {
 19     memset(head,-1,sizeof(head));
 20     cnt = lable = 0;
 21 }
 22 void add(int u,int v,int w)
 23 {
 24     e[cnt].v = v;
 25     e[cnt].w = w;
 26     e[cnt].next = head[u];
 27     head[u] = cnt++;
 28 }
 29 void find_heavy(int rt,int father,int depth)
 30 {
 31 //printf("rt=%d fa=%d \n",rt,father);
 32     fa[rt] = father;
 33     son[rt] = 0;
 34     dep[rt] = depth;
 35     siz[rt] = 1;
 36     int maxsize = 0;
 37     for(int i = head[rt];i!=-1;i = e[i].next)if(e[i].v!=father)
 38     {
 39         e[i].en = e[i^1].en = e[i].v;
 40         find_heavy(e[i].v,rt,depth+1);
 41         siz[rt]+=siz[e[i].v];
 42         if(siz[e[i].v]>maxsize)
 43             maxsize = siz[e[i].v],son[rt] = e[i].v;
 44     }
 45 }
 46 void connect(int rt,int anc)
 47 {
 48     tid[rt] = ++lable;
 49     top[rt] = anc;
 50     if(son[rt])connect(son[rt],anc);
 51     for(int i = head[rt];i!=-1;i = e[i].next)
 52         if(e[i].v!=fa[rt]&&e[i].v!=son[rt])
 53             connect(e[i].v,e[i].v);
 54 }
 55 void pushup(int rt)
 56 {
 57     sum[rt] = sum[rt<<1]+sum[rt<<1|1];
 58 }
 59 void update(int pos,int val,int l,int r,int rt)
 60 {
 61     if(l==r){
 62         sum[rt] = val;
 63         return;
 64     }
 65     int m = (l+r)>>1;
 66     if(pos<=m)update(pos,val,lson);
 67     else update(pos,val,rson);
 68     pushup(rt);
 69 }
 70 int query(int L,int R,int l,int r,int rt)
 71 {
 72     if(L<=l&&r<=R)return sum[rt];
 73     int m = (l+r)>>1,ret = 0;
 74     if(L<=m)ret+=query(L,R,lson);
 75     if(m<R)ret+=query(L,R,rson);
 76     return ret;
 77 }
 78 int getsum(int x,int y)
 79 {
 80     int ans = 0;
 81     while(top[x]!=top[y])
 82     {
 83         if(dep[top[x]]<dep[top[y]])swap(x,y);
 84         ans+=query(tid[top[x]],tid[x],1,n,1);
 85         x = fa[top[x]];
 86     }
 87     if(dep[x]>dep[y])swap(x,y);
 88     if(x==y)return ans;
 89     ans+=query(tid[son[x]],tid[y],1,n,1);
 90     return ans;
 91 }
 92 int main()
 93 {
 94     while(~scanf("%d%d%d",&n,&m,&s))
 95     {
 96         init();
 97         for(int i = 1;i<n;++i)
 98         {
 99             int u,v,w;scanf("%d%d%d",&u,&v,&w);
100             add(u,v,w);
101             add(v,u,w);
102         }
103 //        for(int i = 1;i<=n;++i){
104 //            printf("i=%d:",i);
105 //            for(int j = head[i];j!=-1;j = e[j].next)
106 //            {
107 //                printf("%d ",e[j].v);
108 //                system("pause");
109 //            }
110 //            puts("");
111 //        }
112         find_heavy(1,1,1);//puts("----------");
113         connect(1,1);
114
115         for(int i = 0;i<cnt;i+=2)update(tid[e[i].en],e[i].w,1,n,1);
116         while(m--)
117         {
118             int a,b,c;scanf("%d",&a);
119             if(a){
120                 scanf("%d%d",&b,&c);
121                 update(tid[e[2*b-1].en],c,1,n,1);
122             }
123             else {
124                 scanf("%d",&b);
125                 printf("%d\n",getsum(s,b));
126                 s = b;
127             }
128         }
129     }
130     return 0;
131 }
时间: 2024-08-06 00:38:43

POJ2763 Housewife Wind的相关文章

LCA+线段树/树状数组 POJ2763 Housewife Wind

Housewife Wind Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 11250   Accepted: 3111 Description After their royal wedding, Jiajia and Wind hid away in XX Village, to enjoy their ordinary happy life. People in XX Village lived in beauti

poj2763 Housewife Wind LCA

题目链接: http://poj.org/problem?id=2763 题意: 一个无根树,给出主角一开始所在的位置S,然后下面q个操作,操作包括查询和修改操作,对于查询操作就是当前主角的位置到目的点的距离是多少,然后主角去到那里之后就在那里等待,下次查询的时候那里就是新的起点(所以sample中第二次查询为什么是3).修改是修改第k条边的权值,边的编号就是输入的顺序. 思路: 求树上两点之间的距离,ans=dis[u]+dis[v]-dis[LCA(u,v)]*2; 求LCA这里是用的倍增的

POJ2763 Housewife Wind(DFS序)

题目:单边修改,树链查询. 这题是边权,不是点权,不过也可以看作是点权. 然后其实就和BZOJ2819一样. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 #define MAXN 111111 6 struct Edge{ 7 int u,v,w,nxt; 8 }edge[MAXN<<1]; 9 int n,head[MAXN],N

POJ 2763 Housewife Wind(树链剖分)(线段树单点修改)

Housewife Wind Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 10378   Accepted: 2886 Description After their royal wedding, Jiajia and Wind hid away in XX Village, to enjoy their ordinary happy life. People in XX Village lived in beauti

POJ 2763 Housewife Wind

Housewife Wind Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 8618   Accepted: 2291 Description After their royal wedding, Jiajia and Wind hid away in XX Village, to enjoy their ordinary happy life. People in XX Village lived in beautif

HDOJ 题目2763 Housewife Wind(Link Cut Tree修改边权,查询两点间距离)

Housewife Wind Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 7639   Accepted: 1990 Description After their royal wedding, Jiajia and Wind hid away in XX Village, to enjoy their ordinary happy life. People in XX Village lived in beautif

POJ 2763 Housewife Wind (树链剖分+线段树)

题目链接:POJ 2763 Housewife Wind 题意:抽象出来就是 一棵已知节点之间的边权,两个操作,1·修改边权,2·询问两个节点之间的边权和. AC代码: #include <string.h> #include <stdio.h> #include <algorithm> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int

POJ 2736 Housewife Wind(树链剖分)

POJ 2763 Housewife Wind 题目链接 就树链剖分..不过这题坑ector啊!, vector居然超时 代码: #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; #define lson(x) ((x<<1)+1) #define rson(x) ((x<<1)+2) typ

POJ 2763 Housewife Wind(DFS序+LCA+树状数组)

Housewife Wind Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 11419   Accepted: 3140 Description After their royal wedding, Jiajia and Wind hid away in XX Village, to enjoy their ordinary happy life. People in XX Village lived in beauti