模板【HDU5893 2016 ACM ICPC Asia Regional Shenyang Online B】【树链剖分 权在边上 链值合并 结构体写法】List wants to travel
2016-09-22 10:10
465 查看
List wants to travel
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 727 Accepted Submission(s): 179
[align=left]Problem Description[/align]
A boy named List who is perfect in English. Now he wants to travel and he is making a plan. But the cost of living in same citie always changes. Now he wants to know how many different kinds of continuous same cost he has
to pay for living between two cities. Can you help him? (He is so lazy to do this by himself.)
[align=left]Input[/align]
There are multiple cases. The first line contains two positive numbers N and M(N (N<=40000) where N is the amount of cities and M (M<=50000)) is the amount of operations.Then N-1 lines where each line have 3 integers a b
and c, representing that there is a bidirectionoal road between city a and city b, and the cost is c.(a != b and c <= 100000). Then there are M lines of operation. For example, "Change a b c" means changing all the costs of the road which are passed by him
when he travels from city a to city b to c. "Query a b" means he wants you to tell him how many different kinds of continuous same cost he has to pay traveling from city a to city b.(if a == b, the cost is 0).
[align=left]Output[/align]
He insure you that there is exactly one route between every two different cities.
[align=left]Sample Input[/align]
9 3
1 2 2
2 3 1
1 7 2
1 4 2
3 5 2
3 6 1
5 8 2
5 9 3
Query 1 8
Change 2 6 3
Query 1 6
[align=left]Sample Output[/align]
3
2
[align=left]Source[/align]
2016 ACM/ICPC
Asia Regional Shenyang Online
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<ctype.h>
#include<math.h>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
#include<time.h>
#include<bitset>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x,y) memset(x,y,szof(x))
#define MC(x,y) memcpy(x,y,szof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define ff first
#define ss second
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T> inline void gmax(T &a, T b) { if (b>a)a = b; }
template <class T> inline void gmin(T &a, T b) { if (b<a)a = b; }
const int N = 1e5 + 10, M = N * 2, Z = 1e9 + 7, maxint = 2147483647, ms31 = 522133279, ms63 = 1061109567, ms127 = 2139062143; const double eps = 1e-8, PI = acos(-1.0);//.0
int casenum, casei;
int n, m, id, tim;
int x, y, z; char s[10];
int first
, w[M], c[M], nxt[M];
int u
, v
, fa
, dep
, sz
, pos
, top
;
void ins(int x, int y, int z)
{
id++;
w[id] = y;
c[id] = z;
nxt[id] = first[x];
first[x] = id;
}
//u[x]表示边的编号为x,对应的节点是几号
void dfs1(int x)
{
sz[x] = 1;
for (int z = first[x]; z; z = nxt[z])
{
int y = w[z];
if (y == fa[x])continue;
fa[y] = x;
dep[y] = dep[x] + 1;
u[z] = u[z ^ 1] = y;
dfs1(y);
sz[x] += sz[y];
}
}
void dfs2(int x, int chain)
{
pos[x] = ++tim;
top[x] = chain;
int p = 0;
for (int z = first[x]; z; z = nxt[z])
{
int y = w[z];
if (y != fa[x] && sz[y]>sz[p])p = y;
}
if (p == 0)return;
dfs2(p, chain);
for (int z = first[x]; z; z = nxt[z])
{
int y = w[z];
if (y != fa[x] && y != p)dfs2(y, y);
}
}
int flag[1 << 18];
struct node
{
int num, lc, rc;
}a[1 << 18];
void pushdown(int o)
{
if (flag[o] != 1e9)
{
flag[ls] = flag[rs] = flag[o];
a[ls] = a[rs] = { 1,flag[o],flag[o] };
flag[o] = 1e9;
}
}
node merge(node lc, node rc)
{
return{ lc.num + rc.num - (lc.rc == rc.lc), lc.lc, rc.rc };
}
void build(int o, int l, int r)
{
flag[o] = 1e9;
if (l == r)
{
a[o] = { 1,v[l],v[l] };
return;
}
int mid = (l + r) >> 1;
build(lson);
build(rson);
a[o] = merge(a[ls], a[rs]);
}
int L, R, V;
void color(int o, int l, int r)
{
if (l >= L && r <= R)
{
a[o] = { 1,V,V };
flag[o] = V;
return;
}
pushdown(o);
int mid = (l + r) >> 1;
if (L <= mid)color(lson);
if (R > mid)color(rson);
a[o] = merge(a[ls], a[rs]);
}
node check(int o, int l, int r)
{
if (l >= L && r <= R)return a[o];
pushdown(o);
int mid = (l + r) >> 1;
if (R <= mid)return check(lson);
else if (L > mid)return check(rson);
else return merge(check(lson), check(rson));
}
void COLOR(int x, int y, int z)
{
while (top[x] != top[y])
{
if (dep[top[x]]<dep[top[y]])swap(x, y);
L = pos[top[x]]; R = pos[x]; V = z; color(1, 1, n);
x = fa[top[x]];
}
if (pos[x]>pos[y])swap(x, y);
if (pos[x] < pos[y])
{
L = pos[x] + 1; R = pos[y]; V = z; color(1, 1, n);
}
}
vector< pair<int, int> >up;
vector< pair<int, int> >dn;
int CHECK(int x, int y)
{
if (x == y)return 0;
up.clear();
dn.clear();
while (top[x] != top[y])
{
if (dep[top[x]] > dep[top[y]])
{
up.push_back(MP(pos[top[x]], pos[x]));
x = fa[top[x]];
}
else
{
dn.push_back(MP(pos[top[y]], pos[y]));
y = fa[top[y]];
}
}
if (pos[x] < pos[y])dn.push_back(MP(pos[x] + 1, pos[y]));
else if (pos[y] < pos[x])up.push_back(MP(pos[y] + 1, pos[x]));
node lft = { 0,-1,-1 };
node rgt = { 0,-2,-2 };
for (int i = 0, g = up.size(); i < g; ++i)
{
tie(L, R) = up[i];
lft = merge(check(1, 1, n), lft);
}
for (int i = 0, g = dn.size(); i < g; ++i)
{
tie(L, R) = dn[i];
rgt = merge(check(1, 1, n), rgt);
}
swap(lft.lc, lft.rc);
return merge(lft, rgt).num;
}
int main()
{
//fre();
while (~scanf("%d%d", &n, &m))
{
memset(first, 0, (n + 2) * 4); id = 1;
for (int i = 1; i<n; i++)
{
scanf("%d%d%d", &x, &y, &z);
ins(x, y, z);
ins(y, x, z);
}
fa[1] = 0; dep[1] = 0; dfs1(1);
tim = 0; dfs2(1, 1);
//u[i<<1]是节点
//pos[节点]是节点对应在线段树上的位置
//v[位置]对应的是权值
v[1] = 1e9; for (int i = 1; i < n; i++)v[pos[u[i << 1]]] = c[i << 1];
build(1, 1, n);
while (m--)
{
scanf("%s", s);
if (s[0] == 'C')scanf("%d%d%d", &x, &y, &z), COLOR(x, y, z);
else scanf("%d%d", &x, &y), printf("%d\n", CHECK(x, y));
}
}
return 0;
}
/*
【trick&&吐槽】
链的合并,还是取出lca,然后两端链合并得好
【题意】
给你一棵树,有n(1e5)个节点和m(1e5)个操作
操作1,链(x,y)染色为z([0,1e9])
操作2,问你链(x,y)的颜色段数
【类型】
树链剖分
【分析】
树链剖分+求区间段数,记录区间左右颜色即可。
【时间复杂度&&优化】
O(mlognlogn)
*/
相关文章推荐
- HDU5893 List wants to travel (树链剖分 + 线段树) 2016 ACM/ICPC Asia Regional Shenyang Online
- 2016 ACM/ICPC Asia Regional Shenyang Online HDU 5893 List wants to travel
- 【HDU5892 2016 ACM ICPC Asia Regional Shenyang Online A】【二维树状数组模板 区间修改】nn矩阵内子矩阵中各怪兽数量的奇偶性.cpp
- 2016 ACM/ICPC Asia Regional Shenyang Online HDU 5901 Count Primes (模板 + 数论知识)★
- 2016 ACM/ICPC Reginal Shengyang hdu 5893 List wants to travel(树链剖分 线段树区间更新真蛋疼)★
- HDU 5901 Count Primes (模板 + 数论知识)——2016 ACM/ICPC Asia Regional Shenyang Online
- 2016 ACM/ICPC Asia Regional Shenyang Online 1003/HDU 5894 数学/组合数/逆元
- hdu 5892 List wants to travel 2016ACM/ICPC沈阳赛区网络赛1001
- hdu 5900 QSC and Master 区间dp(2016 ACM/ICPC Asia Regional Shenyang Online)
- HDU 5898 odd-even number (数位DP) 2016 ACM/ICPC Asia Regional Shenyang Online
- HDU 5895 Mathematician QSC(矩阵乘法+循环节降幂+除法取模小技巧+快速幂)——2016 ACM/ICPC Asia Regional Shenyang Online
- 【HDU5894 2016 ACM ICPC Asia Regional Shenyang Online C】【组合数 隔板法】hannnnah_j’s Biological Test n个不同座位成
- 2016 ACM/ICPC Asia Regional Shenyang Online && hdoj5901 Count primes Lehmer
- HDU5900 QSC and Master(区间DP)2016 ACM/ICPC Asia Regional Shenyang Online
- 2016 ACM/ICPC Asia Regional Shenyang Online HDU 5898 odd-even number
- 2016 ACM/ICPC Asia Regional Shenyang Online 1009 QSC and Master 区间dp
- hdu 5893 List wants to travel 2016ACM/ICPC沈阳赛区网络赛1002
- 2016 ACM/ICPC Asia Regional Shenyang Online 1009/HDU 5900 区间dp
- HDU 5895 Mathematician QSC(逆元应用+矩阵快速幂+数论知识)——2016 ACM/ICPC Asia Regional Shenyang Online
- 2015 ACM/ICPC Asia Regional Shenyang Online C. Minimum Cut[树链剖分]