XJOI网上同步训练DAY3 T2
考试的时候已经想出来怎么做了,但是没有时间打了T_T
思路:我们考虑将询问以lim排序,然后树链剖分,把边作为线段树的节点,然后随着询问lim的增大,改变线段树中节点的信息,然后每次询问我们用树链剖分询问,复杂度是O(nlogn),又get一种新的树链剖分打法
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstring>
struct node{
int x,y,lim,id;
}q[];
int V[],dep[],t[],dfn[],num,n,m;
struct Data{
int l,r,s,v;
Data(){}
Data(int a,int b,int c,int d):l(a),r(b),s(c),v(d){}
}s1[],s2[];
Data operator +(Data a,Data b){
Data ret(a.l,b.r,a.s+b.s,a.v+b.v);
if (a.r&&b.l) ret.v=a.v+b.v-V[a.r]-V[b.l]+V[a.r+b.l];
if (b.l==b.s) ret.r=a.r+b.s;
if (a.l==a.s) ret.l=b.l+a.s;
return ret;
}
int tot,go[],next[],first[];
int size[],son[],top[],fa[];
int ans[],val[];
int read(){
int t=,f=;char ch=getchar();
while (ch<''||ch>'') {if (ch=='-') f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
void insert(int x,int y,int z){
tot++;
go[tot]=y;
next[tot]=first[x];
first[x]=tot;
val[tot]=z;
}
void add(int x,int y,int z){
insert(x,y,z);insert(y,x,z);
}
bool cmp(node a,node b){
return a.lim<b.lim;
}
bool cmp1(int x,int y){
return val[x]<val[y];
}
void build(int k,int l,int r){
if (l==r){
s1[k]=s2[k]=Data(,,,V[]);
return;
}
int mid=(l+r)/;
build(k*,l,mid);
build(k*+,mid+,r);
s1[k]=s1[k*]+s1[k*+];
s2[k]=s2[k*+]+s2[k*];
}
void dfs1(int x,int f){
size[x]=;
for (int i=first[x];i;i=next[i]){
int pur=go[i];
if (pur!=f){
dep[pur]=dep[x]+;
t[++t[]]=i;
dfs1(pur,x);
size[x]+=size[pur];
if (size[pur]>size[son[x]]) son[x]=pur;
}
}
}
void dfs2(int x,int f){
dfn[x]=++num;
if (son[x]) top[son[x]]=top[x],dfs2(son[x],x);
for (int i=first[x];i;i=next[i]){
int pur=go[i];
if (pur==f||pur==son[x]) continue;
top[pur]=pur;
fa[pur]=x;
dfs2(pur,x);
}
}
void modify(int k,int l,int r,int pos){
if (l==r){
s1[k]=s2[k]=Data(,,,);
return;
}
int mid=(l+r)/;
if (pos<=mid) modify(k*,l,mid,pos);
else modify(k*+,mid+,r,pos);
s1[k]=s1[k*]+s1[k*+];
s2[k]=s2[k*+]+s2[k*];
}
Data ask1(int k,int l,int r,int x,int y){
if (l==x&&r==y){
return s1[k];
}
int mid=(l+r)/;
if (y<=mid) return ask1(k*,l,mid,x,y);
else
if (x>mid) return ask1(k*+,mid+,r,x,y);
else return ask1(k*,l,mid,x,mid)+ask1(k*+,mid+,r,mid+,y);
}
Data ask2(int k,int l,int r,int x,int y){
if (l==x&&r==y){
return s2[k];
}
int mid=(l+r)/;
if (y<=mid) return ask2(k*,l,mid,x,y);
else
if (x>mid) return ask2(k*+,mid+,r,x,y);
else return ask2(k*+,mid+,r,mid+,y)+ask2(k*,l,mid,x,mid);
}
int work(int x,int y){
Data ans1(,,,),ans2(,,,);
while (top[x]!=top[y]){
if (dep[top[x]]<dep[top[y]]){
ans2=ask1(,,n,dfn[top[y]],dfn[y])+ans2;
y=fa[top[y]];
}else{
ans1=ans1+ask2(,,n,dfn[top[x]],dfn[x]);
x=fa[top[x]];
}
}
if (x!=y){
if (dep[x]<dep[y]){
ans2=ask1(,,n,dfn[son[x]],dfn[y])+ans2;
}else{
ans1=ans1+ask2(,,n,dfn[son[y]],dfn[x]);
}
}
return (ans1+ans2).v;
}
int main(){
freopen("tx.in","r",stdin);
n=read();
for (int i=;i<n;i++) V[i]=read();
for (int i=;i<n;i++){
int x=read()+,y=read()+,v=read();
add(x,y,v);
}
m=read();
for (int i=;i<=m;i++){
q[i].x=read()+,q[i].y=read()+,q[i].lim=read();q[i].id=i;
}
dfs1(,);dfs2(,);
std::sort(q+,q++m,cmp);
std::sort(t+,t++t[],cmp1);
int h=;build(,,n);
for (int i=;i<=m;i++){
while (val[t[h]]<=q[i].lim&&h<=t[]){
modify(,,n,dfn[go[t[h]]]);
h++;
}
ans[q[i].id]=work(q[i].x,q[i].y);
}
for (int i=;i<=m;i++) printf("%d\n",ans[i]);
}
XJOI网上同步训练DAY3 T2的更多相关文章
- XJOI网上同步训练DAY6 T2
思路:记得FJ省队集训好像有过这题,可是我太弱了,根本不懂T_T #include<cstdio> #include<iostream> #include<cmath&g ...
- XJOI网上同步训练DAY3 T1
思路:看来我真是思博了,这么简单的题目居然没想到,而且我对复杂度的判定也有点问题.. 首先我们选了一个位置i的b,那一定只对i和以后的位置造成改变,因此我们可以这样看: 我们从前往后选,发现一个位置的 ...
- XJOI网上同步训练DAY2 T2
[问题描述] 火车司机出秦川跳蚤国王下江南共价大爷游长沙.每个周末勤劳的共价大爷都会开车游历长沙市. 长沙市的交通线路可以抽象成为一个
- XJOI网上同步训练DAY1 T2
思路:似曾相识?...见http://www.cnblogs.com/qzqzgfy/p/5266874.html 一看时限还是4s!,于是就开开心心地打了70%的分,就是用容斥原理,就可以n^3解决 ...
- XJOI网上同步测试DAY14 T2
思路:先考虑在D高度的最小圆覆盖,再一层一层往下走时,可以保证圆心与最开始的圆相同的时候答案是最优的. 时间复杂度O(n) 有一个坑点,就是我用了srand(time(NULL))就T了,RP太差了. ...
- XJOI网上同步训练DAY6 T1
思路:考试的时候直接想出来了,又有点担心复杂度,不过还是打了,居然是直接A掉,开心啊. 我们发现,Ai<=7,这一定是很重要的条件,我们考虑状态压缩,去枚举路径中出现了哪些数字,然后我们把原来n ...
- XJOI网上同步训练DAY5 T1
思路:考虑得出,最终的集合一定是gcd=1的集合,那么我们枚举n个数中哪个数必须选,然后把它质因数分解,由于质数不会超过9个,可以状态压缩,去得出状态为0的dp值就是答案. #include<c ...
- XJOI网上同步训练DAY5 T3
就是对于一个数,我们去考虑把t*****减到(t-1)9999*的代价. #include<cstdio> #include<cmath> #include<algori ...
- XJOI网上同步训练DAY2 T1
[问题描述] 为了迎接校庆月亮中学操场开始施工.不久后操场下发现了很多古墓这些古墓中有很多宝藏.然而学生们逐渐发现自从操场施工之后学校的运气就开始变得特别不好.后来经过调查发现古墓下有一个太守坟由于操 ...
随机推荐
- PCB布线的地线干扰与抑制方法
1.地线的定义什么是地线?大家在教科书上学的地线定义是:地线是作为电路电位基准点的等电位体.这个定义是不符合实际情况的.实际地线上的电位并不是恒定的.如果用仪表测量一下地线上各点之间的电位,会发现地线 ...
- windows批处理命令教程
批处理文件是无格式的文本文件,它包含一条或多条命令.它的文件扩展名为 .bat 或 .cmd.在命令提示下键入批处理文件的名称,或者双击该批处理文件,系统就会调用Cmd.exe按照该文件中各个命令 ...
- 在WPF中使用AForge.net控制摄像头拍照
原文:在WPF中使用AForge.net控制摄像头拍照 利用AForge.net控制摄像头拍照最方便的方法就是利用PictureBox显示摄像头画面,但在WPF中不能直接使用PictureBox.必须 ...
- 为MVC 添加下载权限
今天碰到一个错误,极其郁闷,本地开发和本地部署测试没有问题,但是放到阿里云上,出现了权限问题. 报错:ASP.NET 无权访问所请求的资源.请考虑对 ASP.NET 请求标识授予. 参考网上很多资料, ...
- VS2013中C++创建DLL导出class类
1.创建"Win32 Console Application"项目,命名为"ClassDllLib",并在"Application type" ...
- Address Book(地址薄)
<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.Scene?> ...
- HDU 4274 Spy's Work (树 DFS)
给定N个点,每个点都有一个唯一的前驱结点(点1为大boss),每个点的实际权值是子节点的求和值.现在给出某些点的权值的估算(> , = , < ),问这些估算是否会有冲突,现在保证每个点的 ...
- python calendar标准库基础学习
# -*- coding: utf-8 -*-# 作者:新手__author__ = 'Administrator'#标准库:日期时间基础学习:calendar:处理日期#例1import calen ...
- python lcd 时间显示
#!/usr/bin/python # QStopWatch -- a very simple stop watch # Copyright (C) 2006 Dominic Battre <d ...
- 【转载自i春秋】图片马合成方法
1.将图片和一句话木马放在同一个文件夹 2.创建快捷方式,将起始位置修改为图片和txt文本的路径. 3.进行合成,命令如下 copy .png /b + .txt /a .png 4.成功!自行测试. ...