2016shenyang-1002-HDU5893-List wants to travel-树链剖分+线段树维护不同区间段个数
肯定先无脑树链剖分,然后线段树维护一段区间不同个数,再维护一个左右端点的费用。
线段树更新,pushDown,pushUp的时候要注意考虑链接位置的费用是否相同
还有就是树链剖分操作的时候,维护上一个更新的位置的费用。
总之就是出现区间合并,就考虑总数是否要减一
好想不好写
//场上根本写不完啊
/*--------------------------------------------------------------------------------------*/ #include <algorithm>
#include <iostream>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <cmath>
#include <set>
#include <map> //debug function for a N*M array
#define debug_map(N,M,G) printf("\n");for(int i=0;i<(N);i++)\
{for(int j=;j<(M);j++){\
printf("%d",G[i][j]);}printf("\n");}
//debug function for int,float,double,etc.
#define debug_var(X) cout<<#X"="<<X<<endl;
#define LL long long
const int INF = 0x3f3f3f3f;
const LL LLINF = 0x3f3f3f3f3f3f3f3f;
/*--------------------------------------------------------------------------------------*/
using namespace std; int N,M,T;
const int maxn = 2e5+; struct Edge{
int x,y,val;
}e[maxn]; vector <int> G[maxn]; int val[maxn],dep[maxn],siz[maxn],top[maxn],id[maxn],son[maxn],fa[maxn];
int topw; void init()
{
for(int i=;i<maxn;i++) G[i].clear();
topw = ;
} void dfs_1(int u,int f,int d)
{
fa[u] = f;
son[u] = ;
siz[u] = ;
dep[u] = d;
for(int i=;i<G[u].size();i++) if(G[u][i] != f)
{
dfs_1(G[u][i],u,d+);
siz[u] += siz[G[u][i]];
if(siz[son[u]] < siz[G[u][i] ])
{
son[u] = G[u][i];
}
}
} void dfs_2(int u,int tp)
{
top[u] = tp;
id[u] = ++topw;
if(son[u]) dfs_2(son[u],tp);
for(int i=;i<G[u].size();i++) if(G[u][i]!=fa[u] && G[u][i] != son[u] )
{
dfs_2(G[u][i],G[u][i]);
}
} void debug()
{
for(int i=;i<=N;i++)
{
printf("%d siz:%d son:%d dep:%d fa:%d ",i,siz[i],son[i],dep[i],fa[i]);
printf("top:%d id:%d\n",top[i],id[i]);
}
return ;
} /*-----------------------------------*/
#define lson(x) (x<<1)
#define rson(x) (x<<1|1) struct SegmentTree{
int l,r;
int lazy;
int num,lcost,rcost;
}segtree[*maxn]; void pushUp(int x)
{
segtree[x].num = segtree[lson(x)].num + segtree[rson(x)].num - (segtree[lson(x)].rcost==segtree[rson(x)].lcost? : );
segtree[x].lcost = segtree[lson(x)].lcost;
segtree[x].rcost = segtree[rson(x)].rcost;
//printf("x:%d [%d,%d] num:%d\n",x,segtree[x].l,segtree[x].r,segtree[x].num);
//printf("lcost:%d rcost:%d\n",segtree[x].lcost,segtree[x].rcost);
//printf("l->rcost:%d r->lcost:%d\n",segtree[lson(x)].rcost,segtree[rson(x)].lcost);
} void pushDown(int x)
{
if(segtree[x].lazy != -)
{
segtree[lson(x)].lcost = segtree[lson(x)].rcost = segtree[x].lazy;
segtree[rson(x)].lcost = segtree[rson(x)].rcost = segtree[x].lazy;
segtree[lson(x)].num = segtree[rson(x)].num = ;
segtree[lson(x)].lazy = segtree[rson(x)].lazy = segtree[x].lazy;
segtree[x].lazy = -;
}
} void Build(int l,int r,int x)
{
segtree[x].l = l;
segtree[x].r = r;
segtree[x].lazy = -;
if(l == r)
{
segtree[x].num = ;
segtree[x].lcost = segtree[x].rcost = val[l];
return ;
}
int mid = (l+r)>>;
Build(l,mid,lson(x));
Build(mid+,r,rson(x));
pushUp(x);
} void update(int x,int L,int R,int cost)
{
if(segtree[x].l >= L && segtree[x].r <= R)
{
segtree[x].lcost = segtree[x].rcost = cost;
segtree[x].num = ;
segtree[x].lazy = cost;
return ;
}
pushDown(x);
int mid = (segtree[x].l + segtree[x].r) >> ;
if(L <= mid) update(lson(x),L,R,cost);
if(R > mid) update(rson(x),L,R,cost);
pushUp(x);
return ;
} int query(int x,int L,int R)
{
if(segtree[x].l >= L && segtree[x].r <= R)
{
return segtree[x].num;
}
pushDown(x);
int mid = (segtree[x].l + segtree[x].r) >> ;
int ans = ; if(R <= mid) ans = query(lson(x),L,R);
else if(L > mid) ans = query(rson(x),L,R);
else ans = query(lson(x),L,R) + query(rson(x),L,R) - (segtree[lson(x)].rcost==segtree[rson(x)].lcost ? : ) ;
pushUp(x);
return ans;
} int query_edge(int x,int pos)
{
if(segtree[x].l == segtree[x].r)
{
return segtree[x].lcost;
}
pushDown(x);
int res = ;
int mid = (segtree[x].l + segtree[x].r) >> ;
if(pos <= mid) res = query_edge(lson(x),pos);
else res = query_edge(rson(x),pos);
pushUp(x);
return res ;
} int Find(int u,int v)
{
int ans = ,fu = top[u],fv = top[v];
int last_u=- , last_v = -;
int last_u_color,last_v_color;
//printf("%d->%d\n",u,v); while(fu != fv)
{
if(dep[fu] < dep[fv])
{
swap(fu,fv);swap(u,v);
swap(last_u,last_v);
swap(last_u_color,last_v_color);
} //printf("query:[%d,%d] %d->%d ",id[fu],id[u],u,fu);
//printf("%d\n",query(1,id[fu],id[u]));
ans += query(,id[fu],id[u]);
if(last_u == -)
{
last_u = fu;
last_u_color = query_edge(,id[fu]);
}
else
{
if(last_u != - && fa[last_u] == u)
{
//printf("u sub:%d\n",(last_u_color==query_edge(1,id[u]) ? 1 : 0));
ans -= (last_u_color==query_edge(,id[u]) ? : );
last_u = fu;
last_u_color = query_edge(,id[fu]);
}
}
u = fa[fu];
fu = top[u];
}
if(u == v)
{
if(last_u != - && last_v != - && last_u_color==last_v_color) ans -= ;
return ans;
}
if(dep[u] < dep[v])
{
swap(u,v);
swap(last_u,last_v);
swap(last_u_color,last_v_color);
}
//printf("query:[%d,%d] %d->%d ",id[son[v]],id[u],u,son[v]);
ans += query(,id[son[v] ],id[u]);
//printf("%d*\n",query(1,id[son[v]],id[u])); //printf("last_u:%d last_v:%d\n",last_u,last_v);
if(last_u != - && fa[last_u] == u)
{
//printf("u sub:%d last_u_color:%d u_color:%d\n",(last_u_color==query_edge(1,id[u]) ? 1 : 0),last_u_color,query_edge(1,id[u]));
ans -= (last_u_color==query_edge(,id[u]) ? : );
last_u = fu;
last_u_color = query_edge(,id[u]);
} if(last_v != - && fa[last_v] == v)
{
//printf("v sub:%d last_v_color:%d son[v]_color:%d\n",(last_v_color==query_edge(1,id[son[v]]) ? 1 : 0),last_v_color,query_edge(1,id[son[v]] ));
ans -= (last_v_color==query_edge(,id[son[v]]) ? : );
last_v = fv;
last_v_color = query_edge(,id[son[v]]);
} return ans;
} void Change(int u,int v,int cost)
{
int fu = top[u],fv = top[v];
//printf("%d->%d\n",u,v);
while(fu != fv)
{
if(dep[fu] < dep[fv])
{
swap(fu,fv);swap(u,v);
}
//printf("change:[%d,%d] %d->%d %d\n",id[fu],id[u],u,fu,cost);
update(,id[fu],id[u],cost);
u = fa[fu];
fu = top[u];
}
if(u == v) return ;
if(dep[u] < dep[v]) swap(u,v);
//printf("change:[%d,%d] %d->%d %d\n",id[son[v]],id[u],u,son[u],cost);
update(,id[son[v]],id[u],cost);
return ;
} int main()
{
//freopen("input","r",stdin);
while(~scanf("%d%d",&N,&M))
{
init();
int u,v,w;
for(int i=;i<N;i++)
{
scanf("%d%d%d",&u,&v,&w);
e[i].x = u;e[i].y = v;e[i].val = w;
G[u].push_back(v);
G[v].push_back(u);
}
topw = ;
dfs_1(,,);
dfs_2(,);
//debug();
for(int i=;i<N;i++)
{
if(dep[e[i].x] < dep[e[i].y]) swap(e[i].x,e[i].y);
val[id[e[i].x]] = e[i].val;
} Build(,topw,);
char op[];
//printf("-----------------\n");
for(int i=;i<M;i++)
{
scanf("%s",op);
if(op[] == 'Q')
{
scanf("%d%d",&u,&v);
printf("%d\n",Find(u,v));
}
else
{
scanf("%d%d%d",&u,&v,&w);
Change(u,v,w);
}
//puts("");
}
}
}
2016shenyang-1002-HDU5893-List wants to travel-树链剖分+线段树维护不同区间段个数的更多相关文章
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- bzoj4034 (树链剖分+线段树)
Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...
- HDU4897 (树链剖分+线段树)
Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...
- Aizu 2450 Do use segment tree 树链剖分+线段树
Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...
- 【POJ3237】Tree(树链剖分+线段树)
Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...
- HDU 2460 Network(双连通+树链剖分+线段树)
HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...
- bzoj2243[SDOI2011]染色 树链剖分+线段树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 9012 Solved: 3375[Submit][Status ...
随机推荐
- mysql 判断表字段或索引是否存在
判断字段是否存在: DROP PROCEDURE IF EXISTS schema_change; DELIMITER // CREATE PROCEDURE schema_change() BEGI ...
- 网络编程3--毕向东java基础教程视频学习笔记
Day24 01 TCP上传图片02 客户端并发上传图片03 客户端并发登录04 浏览器客户端-自定义服务端05 浏览器客户端-Tomcat服务端 01 TCP上传图片 import java.net ...
- (ios) nsnotification总结
1 文本输入,键盘显示时,view向上,键盘隐藏时,view向下 1.1 注册键盘显示,关闭通知,并实现主界面上下变动 [[NSNotificationCenter defaultCenter] a ...
- SQL Server 2012实施与管理实战指南(笔记)——Ch5启动SQL Server服务和数据库
5.启动SQL Server服务和数据库 在数据库和服务启动过程中,经常会出现的问题: 1.SQL Server实例无法正常启动 2.系统数据库无法正常启动 3.网络配置失败 4.用户数据库无法启动 ...
- AS与.net的交互——详解UrlRequest
在.net中我们知道有一个叫做WebHttpRequest的东西,用它我们可以实现各种网络偷窥,监控,采集和机器人,如果外加一 个模式识别,那真是吊爆了... 在as中我们也可以实现同样的功能,而且我 ...
- x01.BitmapHelper:图像处理
“所有致我于死地的,也激发我胆魄”,姚贝娜的<心火>,是我近年来听过最好的歌,特此推荐一下. 图像处理,大概分三步:1.LockBits():2.进行处理:3.UnlockBits():这 ...
- Python使用QRCode模块生成二维码
QRCode官网https://pypi.python.org/pypi/qrcode/5.1 简介python-qrcode是个用来生成二维码图片的第三方模块,依赖于 PIL 模块和 qrcode ...
- ELF Format 笔记(七)—— 符号表
最是那一低头的温柔,像一朵水莲花不胜凉风的娇羞,道一声珍重,道一声珍重,那一声珍重里有蜜甜的忧愁 —— 徐志摩 ilocker:关注 Android 安全(新手) QQ: 2597294287 符号表 ...
- C 运算符优先级
优先级 运算符 名称或含义 使用形式 结合方向 说明 1 [] 数组下标 数组名[常量表达式] 左到右 () 圆括号 (表达式)/函数名(形参表) . 成员选择(对象) 对象.成员名 -& ...
- Stanford机器学习笔记-4. 神经网络Neural Networks (part one)
4. Neural Networks (part one) Content: 4. Neural Networks (part one) 4.1 Non-linear Classification. ...