D. Happy Tree Party

Time Limit: 20 Sec

Memory Limit: 256 MB

题目连接

http://codeforces.com/contest/593/problem/D

Description

Bogdan has a birthday today and mom gave him a tree consisting of n vertecies. For every edge of the tree i, some number xi was written on it. In case you forget, a tree is a connected non-directed graph without cycles. After the present was granted, m guests consecutively come to Bogdan's party. When the i-th guest comes, he performs exactly one of the two possible operations:

  1. Chooses some number yi, and two vertecies ai and bi. After that, he moves along the edges of the tree from vertex ai to vertex bi using the shortest path (of course, such a path is unique in the tree). Every time he moves along some edge j, he replaces his current number yi by , that is, by the result of integer division yi div xj.
  2. Chooses some edge pi and replaces the value written in it xpi by some positive integer ci < xpi.

As Bogdan cares about his guests, he decided to ease the process. Write a program that performs all the operations requested by guests and outputs the resulting value yi for each i of the first type.

Under two situations the player could score one point.

⋅1. If you touch a buoy before your opponent, you will get one point. For example if your opponent touch the buoy #2 before you after start, he will score one point. So when you touch the buoy #2, you won't get any point. Meanwhile, you cannot touch buoy #3 or any other buoys before touching the buoy #2.

⋅2. Ignoring the buoys and relying on dogfighting to get point.
If you and your opponent meet in the same position, you can try to
fight with your opponent to score one point. For the proposal of game
balance, two players are not allowed to fight before buoy #2 is touched by anybody.

There are three types of players.

Speeder:
As a player specializing in high speed movement, he/she tries to avoid
dogfighting while attempting to gain points by touching buoys.
Fighter:
As a player specializing in dogfighting, he/she always tries to fight
with the opponent to score points. Since a fighter is slower than a
speeder, it's difficult for him/her to score points by touching buoys
when the opponent is a speeder.
All-Rounder: A balanced player between Fighter and Speeder.

There will be a training match between Asuka (All-Rounder) and Shion (Speeder).
Since the match is only a training match, the rules are simplified: the game will end after the buoy #1 is touched by anybody. Shion is a speed lover, and his strategy is very simple: touch buoy #2,#3,#4,#1 along the shortest path.

Asuka is good at dogfighting, so she will always score one point by dogfighting with Shion, and the opponent will be stunned for T seconds after dogfighting.
Since Asuka is slower than Shion, she decides to fight with Shion for
only one time during the match. It is also assumed that if Asuka and
Shion touch the buoy in the same time, the point will be given to Asuka
and Asuka could also fight with Shion at the buoy. We assume that in
such scenario, the dogfighting must happen after the buoy is touched by
Asuka or Shion.

The speed of Asuka is V1 m/s. The speed of Shion is V2 m/s. Is there any possibility for Asuka to win the match (to have higher score)?

Input

The first line of the input contains integers, n and m (2 ≤ n ≤ 200 000, 1 ≤ m ≤ 200 000) — the number of vertecies in the tree granted to Bogdan by his mom and the number of guests that came to the party respectively.

Next n - 1 lines contain the description of the edges. The i-th of these lines contains three integers ui, vi and xi (1 ≤ ui, vi ≤ n, ui ≠ vi, 1 ≤ xi ≤ 1018), denoting an edge that connects vertecies ui and vi, with the number xi initially written on it.

The following m lines describe operations, requested by Bogdan's guests. Each description contains three or four integers and has one of the two possible forms:

  • 1 ai bi yi corresponds to a guest, who chooses the operation of the first type.
  • 2 pi ci corresponds to a guests, who chooses the operation of the second type.

It is guaranteed that all the queries are correct, namely 1 ≤ ai, bi ≤ n, 1 ≤ pi ≤ n - 1, 1 ≤ yi ≤ 1018 and 1 ≤ ci < xpi, where xpi represents a number written on edge pi at this particular moment of time that is not necessarily equal to the initial value xpi, as some decreases may have already been applied to it. The edges are numbered from 1 to n - 1 in the order they appear in the input.

Output

For each guest who chooses the operation of the first type, print the result of processing the value yi through the path from ai to bi.

Sample Input

6 6
1 2 1
1 3 7
1 4 4
2 5 5
2 6 2
1 4 6 17
2 3 2
1 4 6 17
1 5 5 20
2 4 1
1 5 1 3
 

Sample Output

2
4
20
3

HINT

题意

给你一颗树,然后有两个操作

1 x y z,假设x到y的链上边权分别为x1,x2,x3....,那么输出 [[[z/x1]/x2]/x3]

2 x y,把第x条边的边权改为y

题解:

有一个结论 [[[z/x1]/x2]/x3] = [z/(x1*x2*x3)]

那么我们只要维护区间乘积就好了,树链剖分裸题

但是区间乘积很容易爆LL,那么我们就用一个log来判断,如果爆了ll,那就直接把他置为1e18

然后答案直接输出0就好了

代码

#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <math.h>
using namespace std;
const int N=;
const int INF=<<; int n,tim; long long num[N];
int siz[N],top[N],son[N];
int dep[N],tid[N],Rank[N],fa[N];
int head[N],to[*N],Next[*N],w[*N],edge;
int flag = ;
struct Edge
{
int u,v;
long long c;
};
Edge tmp[*N]; void Init()
{
memset(head,-,sizeof(head));
memset(son,-,sizeof(son));
tim=;
edge=;
} void addedge(int u,int v,int c)
{
to[edge]=v,w[edge]=c,Next[edge]=head[u],head[u]=edge++;
to[edge]=u,w[edge]=c,Next[edge]=head[v],head[v]=edge++;
} //树链剖分部分
void dfs1(int u,int father,int d)
{
dep[u]=d;
fa[u]=father;
siz[u]=;
for(int i=head[u]; ~i; i=Next[i])
{
int v=to[i];
if(v!=father)
{
dfs1(v,u,d+);
siz[u]+=siz[v];
if(son[u]==-||siz[v]>siz[son[u]])
son[u]=v;
}
}
} void dfs2(int u,int tp)
{
top[u]=tp;
tid[u]=++tim;
Rank[tid[u]]=u;
if(son[u]==-) return;
dfs2(son[u],tp);
for(int i=head[u]; ~i; i=Next[i])
{
int v=to[i];
if(v!=son[u]&&v!=fa[u])
dfs2(v,v);
}
} //线段树部分
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const long long kkk = 1e18+;
long long MAX[*N]; void PushUP(int rt)
{
if(MAX[rt<<]==)
MAX[rt]=;
if(MAX[rt<<|]==)
MAX[rt<<|]=;
double ppp1 = MAX[rt<<];
double ppp2 = MAX[rt<<|];
if(log(ppp1) + log(ppp2) > log(kkk * 1.0))
MAX[rt]=kkk+;
else
MAX[rt]=MAX[rt<<]*MAX[rt<<|];
} void Build(int l,int r,int rt)
{
if(l==r)
{
MAX[rt]=num[l];
return;
}
int mid=(l+r)>>;
Build(lson);
Build(rson);
PushUP(rt);
} void Update(int l,int r,int rt,int p,long long val)
{
if(l==r)
{
MAX[rt]=val;
return;
}
int mid=(l+r)>>;
if(p<=mid)
Update(lson,p,val);
else
Update(rson,p,val);
PushUP(rt);
} long long Query(int l,int r,int rt,int L,int R)
{
if(L<=l&&R>=r)
return MAX[rt];
int mid=(l+r)>>;
long long ans=;
if(L<=mid)
{
long long kkkk = Query(lson,L,R);
if(kkkk==-)
flag = ;
if(log(ans*1.0) + log(kkkk*1.0) > log(kkk*1.0))
ans = kkk+;
else
ans*=kkkk;
}
if(R>mid)
{
long long kkkk = Query(rson,L,R);
if(kkkk==-)
flag = ;
if(log(ans*1.0) + log(kkkk*1.0) > log(kkk*1.0))
ans = kkk+;
else
ans*=kkkk;
}
return ans;
} void Change(int x,long long val)
{
if(dep[tmp[x].u]>dep[tmp[x].v])
Update(,n,,tid[tmp[x].u],val);
else
Update(,n,,tid[tmp[x].v],val);
} long long query(int x,int y)
{
long long ans=;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
long long kkkk = Query(,n,,tid[top[x]],tid[x]);
if(log(ans*1.0) + log(kkkk*1.0) > log(kkk*1.0))
ans = kkk+;
else
ans*=kkkk;
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
if(x!=y)
{
long long kkkk =Query(,n,,tid[x]+,tid[y]);
if(log(ans*1.0) + log(kkkk*1.0) > log(kkk*1.0))
ans = kkk+;
else
ans*=kkkk;
}
return ans;
}
int MM;
int main()
{
char oper[];
int a,b;
long long c;
Init();
scanf("%d%d",&n,&MM);
for(int i=; i<n; i++)
{
scanf("%d%d%lld",&a,&b,&c);
tmp[i].u=a;tmp[i].v=b;tmp[i].c=c;
addedge(a,b,c);
}
dfs1(,,);
dfs2(,);
//用边的孩子节点来表示该边
for(int i=;i<n;i++)
{
if(dep[tmp[i].u]>dep[tmp[i].v])
num[tid[tmp[i].u]]=tmp[i].c;
else
num[tid[tmp[i].v]]=tmp[i].c;
}
Build(,n,);
while(MM--)
{
scanf("%s",oper);
if(oper[]=='')
{
long long ppp;
scanf("%d%d",&a,&b);
scanf("%lld",&ppp);
flag = ;
long long dddd = query(a,b);
printf("%lld\n",ppp/dddd);
}
else
{
long long ppp;
scanf("%d%lld",&a,&ppp);
Change(a,ppp);
}
}
return ;
}

Codeforces Round #329 (Div. 2) D. Happy Tree Party 树链剖分的更多相关文章

  1. Codeforces Round #329 (Div. 2) D. Happy Tree Party LCA/树链剖分

    D. Happy Tree Party     Bogdan has a birthday today and mom gave him a tree consisting of n vertecie ...

  2. Codeforces Round #329 (Div. 2) D. Happy Tree Party(LCA+并查集)

    题目链接 题意:就是给你一颗这样的树,用一个$y$来除以两点之间每条边的权值,比如$3->7$,问最后的y的是多少,修改操作是把权值变成更小的. 这个$(y<=10^{18})$除的权值如 ...

  3. Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+ 树状数组或线段树

    C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/p ...

  4. Codeforces Round #200 (Div. 1) D Water Tree 树链剖分 or dfs序

    Water Tree 给出一棵树,有三种操作: 1 x:把以x为子树的节点全部置为1 2 x:把x以及他的所有祖先全部置为0 3 x:询问节点x的值 分析: 昨晚看完题,马上想到直接树链剖分,在记录时 ...

  5. Codeforces Round #200 (Div. 1) D. Water Tree 树链剖分+线段树

    D. Water Tree time limit per test 4 seconds memory limit per test 256 megabytes input standard input ...

  6. Codeforces Round #200 (Div. 1)D. Water Tree

    简单的树链剖分+线段树 #include<bits\stdc++.h> using namespace std; #define pb push_back #define lson roo ...

  7. 【POJ3237】Tree(树链剖分)

    题意:在一棵N个节点,有边权的树上维护以下操作: 1:单边修改,将第X条边的边权修改成Y 2:区间取反,将点X与Y在树上路径中的所有边边权取反 3:区间询问最大值,询问X到Y树上路径中边权最大值 n& ...

  8. HDU 4718 The LCIS on the Tree(树链剖分)

    Problem Description For a sequence S1, S2, ... , SN, and a pair of integers (i, j), if 1 <= i < ...

  9. POJ 3237:Tree(树链剖分)

    http://poj.org/problem?id=3237 题意:树链剖分.操作有三种:改变一条边的边权,将 a 到 b 的每条边的边权都翻转(即 w[i] = -w[i]),询问 a 到 b 的最 ...

随机推荐

  1. 【DFS,双向】NYOJ-20-吝啬的国度

    [题目链接:NYOJ-20] 很巧妙,要好好想想 #include <iostream> #include <stdio.h> #include <vector> ...

  2. TCP/IP详解学习笔记(7)-广播和多播,IGMP协议

    1.单播,多播,广播的介绍 1.1.单播(unicast) 单播是说,对特定的主机进行数据传送.例如给某一个主机发送IP数据包.这时候,数据链路层给出的数据头里面是非常具体的目的地址,对于以太网来 说 ...

  3. MySQL auto_increment的坑

    背景: Innodb引擎使用B_tree结构保存表数据,这样就需要一个唯一键表示每一行记录(比如二级索引记录引用). Innodb表定义中处理主键的逻辑是: 1.如果表定义了主键,就使用主键唯一定位一 ...

  4. 【转】简单内存泄漏检测方法 解决 Detected memory leaks! 问题

    我的环境是: XP SP2 . VS2003 最近在一个项目中,程序退出后都出现内存泄漏: Detected memory leaks! Dumping objects -> {98500} n ...

  5. UVALive 4255 Guess

    这题竟然是图论···orz 题意:给出一个整数序列a1,a2,--,可以得到如下矩阵 1 2 3 4 1 - + 0 + 2   + + + 3       -  - 4         + &quo ...

  6. IOS 点击按钮 光环 冲击波效果

    UIBezierPath * path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(0, 0) radius:ROUND_WIDTH/2 - ...

  7. 【LR】录制测试脚本中的基本菜单

    学习来源: MBoo,小强老师性能测试及Loadrunner培训  ——录制测试脚本: 1.Vuser -> run-time settings ->General Run Logic : ...

  8. <转>Python 参数知识(变量前加星号的意义)

    csdn上的牛人就是多,加油 —————————————————————————— 过量的参数 在运行时知道一个函数有什么参数,通常是不可能的.另一个情况是一个函数能操作很多对象.更有甚者,调用自身的 ...

  9. 《零成本实现Web自动化测试--基于Selenium》第三章 Selenium-IDE

    1.简介 Selenium-IDE(集成开发环境)是一种开发selenium测试案例的工具.是一种易用的Firefox插件.你可以通过文字菜单,在当前页面上选择一个UI元素,接着挑选与UI元素相关的s ...

  10. ASP.net MVC基础

    简单了解了下MVC的基本开发步骤后,又对MVC的语法和模版详细看看了,小小总结下 对mvc开发,首先是要对布局有个基本的认识.Razor引擎使页面元素更加清晰 简单认识下 可以加载css和js等文件, ...