poj 2763 Housewife Wind(树链剖分,边权)
来源:互联网 发布:谁用过网络麻将开挂 编辑:程序博客网 时间:2024/06/04 18:04
题目链接
题意:给出一颗树,初始在s点,有2个操作0操作,表示求s到u路径和
1操作表示把第i条边权重变为w。
树链剖分,然后用线段树维护就可以了
//#include<bits/stdc++.h>#include<iostream>#include<cstdio>#include<algorithm>#include<vector>#include<queue>#include<stack>#include<cstring>#include<set>#include<map>#include<string>#include<cassert>using namespace std;#define cl(a,b) memset(a,b,sizeof(a))#define fastIO ios::sync_with_stdio(false);cin.tie(0);#define ll long long#define pb push_back#define gcd __gcd#define For(i,j,k) for(int i=(j);i<=k;i++)#define lowbit(i) (i&(-i))#define _(x) printf("%d\n",x)typedef vector<ll> vec;typedef pair<int,int> PI;const double EPS = 1e-8;const int maxn = 2e5+100;const int inf = 1 << 28;int n,q,s;int e[maxn][3];struct Edge{ int to,next;}es[maxn<<2];int head[maxn],tot;int top[maxn];int p[maxn];int fa[maxn];int fp[maxn];int num[maxn];int deep[maxn];int son[maxn];int pos;void addEdge(int u,int v){ es[tot].to=v;es[tot].next=head[u];head[u]=tot++;}void init(){ tot=0; cl(head,-1); pos=0; cl(son,-1);}void dfs(int u,int pre,int d){ deep[u]=d; fa[u]=pre; num[u]=1; for(int i=head[u];~i;i=es[i].next){ int v=es[i].to; if(v!=pre){ dfs(v,u,d+1); num[u]+=num[v]; if(son[u]==-1||num[son[u]]<num[v])son[u]=v; } }}void getpos(int u,int sp){ top[u]=sp; p[u]=pos++; fp[p[u]]=u; if(son[u]==-1)return ; getpos(son[u],sp); for(int i=head[u];~i;i=es[i].next){ int v=es[i].to; if(v!=fa[u]&&v!=son[u])getpos(v,v); }}//int sum[maxn<<2];void pushUp(int rt){ sum[rt]=sum[rt<<1]+sum[rt<<1|1];}void build(int rt,int l,int r){ if(l==r){ sum[rt]=e[fp[l]][2]; return ; } int mid=l+r>>1; build(rt<<1,l,mid); build(rt<<1|1,mid+1,r); pushUp(rt);}void update(int rt,int l,int r,int i,int v){ if(l==i&&r==i){ sum[rt]=v; return ; } int mid=l+r>>1; if(i<=mid)update(rt<<1,l,mid,i,v); else update(rt<<1|1,mid+1,r,i,v); pushUp(rt);}int query(int rt,int l,int r,int x,int y){ if(x<=l&&r<=y){ return sum[rt]; } int mid=l+r>>1; int ans=0; if(x<=mid)ans+=query(rt<<1,l,mid,x,y); if(y>mid)ans+=query(rt<<1|1,mid+1,r,x,y); return ans;}int findSum(int u,int v){ int f1=top[u],f2=top[v]; int ans=0; while(f1!=f2){ if(deep[f1]<deep[f2]){ swap(f1,f2); swap(v,u); } ans+=query(1,0,pos-1,p[f1],p[u]); u=fa[f1];f1=top[u]; } if(u==v)return ans; if(deep[u]>deep[v])swap(u,v); ans+=query(1,0,pos-1,p[son[u]],p[v]); return ans;}int main(){ while(~scanf("%d%d%d",&n,&q,&s)){ init(); for(int i=1;i<n;i++){ scanf("%d%d%d",&e[i][0],&e[i][1],&e[i][2]); addEdge(e[i][0],e[i][1]); addEdge(e[i][1],e[i][0]); } dfs(1,0,0); getpos(1,1); //build(1,0,pos-1); for(int i=1;i<n;i++){ if(deep[e[i][0]]<deep[e[i][1]])swap(e[i][0],e[i][1]); update(1,0,pos-1,p[e[i][0]],e[i][2]); } while(q--){ int t;scanf("%d",&t); if(t){ int i,v; scanf("%d%d",&i,&v); if(deep[e[i][0]]<deep[e[i][1]])swap(e[i][0],e[i][1]); update(1,0,pos-1,p[e[i][0]],v); } else { int u;scanf("%d",&u); printf("%d\n",findSum(s,u)); s=u; } } } return 0;}
0 0
- 【树链剖分】 POJ 2763 Housewife Wind 边权
- POJ 2763 Housewife Wind 树链剖分 边权
- poj 2763 Housewife Wind(树链剖分,边权)
- POJ 2763 Housewife Wind(树链剖分(边权))
- poj 2763 Housewife Wind(树链剖分,边权)
- poj 2763 Housewife Wind(树链剖分)
- POJ 2763 Housewife Wind 树链剖分
- POJ 2763 Housewife Wind 树链剖分
- poj 2763 Housewife Wind(树链剖分)
- poj 2763 Housewife Wind 树链剖分
- POJ 2763 Housewife Wind (树链剖分)
- POJ 2763 Housewife Wind 树链剖分
- POJ 2763 Housewife Wind(树链剖分)
- poj 2763 Housewife Wind 树链剖分
- POJ 2763Housewife Wind 树链剖分
- POJ 2763 Housewife Wind (树链剖分)
- POJ 2763 Housewife Wind
- POJ 2763 Housewife Wind
- JSP项目在网页中实现查询
- oracle 有关emp表的练习题
- 不带缓存的IO操作
- Linux之ln命令
- Solr-----7、Solr使用DataImportHandler导入数据库数据
- poj 2763 Housewife Wind(树链剖分,边权)
- hdu 2064 汉诺塔III
- cesuim自学(一):环境搭建
- lintcode刷题10.27
- android最基础简单的ListView实现方法
- 进程调度之FCFS
- ⑤盲注
- 数据结构-栈
- 选择排序,冒泡排序,二分搜索,插入排序,归并排序