题目描述

Description

有一个n个点A+B条边的无向连通图,有一变量x,每条边的权值都是一个关于x的简单多项式,其中有A条边的权值是k+x,另外B条边的权值是k-x,如果只保留权值形如k+x的边,那么这个图仍是一个连通图,如果只保留权值形如k-x的边,这个图也依然是一个连通图。

给出q组询问,每组询问给出x的值,问此时这个无向连通图的最小生成树权值是多少。

Input

第一行四个数n,A,B和q

接下来A行,每行三个整数u,v,k,表示u和v之间有一条权值为k+x的无向边

接下来B行,每行三个整数u,v,k,表示u和v之间有一条权值为k-x的无向边

接下来q行,每行一个整数v,问当x=v时图的最小生成树权值是多少

Output

输出共q行,每行一个数表示对应询问的答案

Sample Input

5 4 4 4
1 3 2
1 2 0
3 5 5
3 4 10
5 4 7
2 3 6
1 2 1000
3 4 1000
0
1
2
3

Sample Output

14
16
18
18

Data Constraint

对于30%的数据,1<=n,q<=1000,n-1<=A,B<=2000

对于另外20%的数据,所有权值形如k+x的边的k满足,0<=k<=108,所有权值形如k-x的边的k满足9*108<=k<=109,所有询问的v满足0<=v<=4*108

对于另外40%的数据,1<=n<=1000,1<=q<=100000,n-1<=A,B<=2000

对于100%的数据,1<=n,q<=100000 , n-1<=A,B<=200000, 0<=k<=10^9 , -109<=v<=109

题解

显然按照正边和负边分别搞,每次加上一条负边,把树上最大的正边删掉

LCT搞边权=把边建点

code

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
using namespace std; struct type{
int x,y,s;
} a[200001],b[200001];
int a2[200001];
struct Type{
int x,id;
} q[100001];
struct TYPE{
double x;
int s;
} c[200001];
int tr[500001][2];
int Tr[500001][2];
int TR[500001];
bool rev[500001];
bool bz[500001]; //is root
int K[500001];
int fa[500001];
int Fa[100001];
long long ans[100001];
int n,A,B,Q,i,j,k,l,len,N;
long long sum; void look()
{
int i; fo(i,1,len)
cout<<"son:"<<tr[i][0]<<" "<<tr[i][1]<<" father:"<<fa[i]<<" isroot:"<<bz[i]<<" reverse:"<<rev[i]<<" max:"<<Tr[i][0]<<" "<<Tr[i][1]<<endl;
cout<<endl;
} bool cmp(type a,type b)
{
return a.s<b.s;
}
bool Cmp(Type a,Type b)
{
return a.x<b.x;
}
bool CMP(TYPE a,TYPE b)
{
return a.x<b.x;
} int gf(int t)
{
if (Fa[t]==t) return t; Fa[t]=gf(Fa[t]);
return Fa[t];
} void swap(int &x,int &y)
{
int z=x;
x=y;
y=z;
} void up(int t)
{
Tr[t][0]=a[TR[t]].s;
Tr[t][1]=TR[t]; if (tr[t][0] && Tr[tr[t][0]][0]>Tr[t][0])
{
Tr[t][0]=Tr[tr[t][0]][0];
Tr[t][1]=Tr[tr[t][0]][1];
}
if (tr[t][1] && Tr[tr[t][1]][0]>Tr[t][0])
{
Tr[t][0]=Tr[tr[t][1]][0];
Tr[t][1]=Tr[tr[t][1]][1];
}
} void down(int t)
{
if (rev[t])
{
swap(tr[t][0],tr[t][1]);
rev[t]=0; rev[tr[t][0]]^=1;
rev[tr[t][1]]^=1;
}
} void rot(int t)
{
down(fa[t]);
down(t); int Fa=fa[t],Fa2=fa[Fa],x=tr[Fa][1]==t,x2=tr[Fa2][1]==Fa,son=tr[t][x^1]; fa[son]=Fa;
tr[Fa][x]=son; tr[t][x^1]=Fa;
fa[Fa]=t; if (!bz[Fa])
tr[Fa2][x2]=t;
fa[t]=Fa2; bz[t]=bz[Fa];
bz[Fa]=0; up(Fa);
up(t);
} void splay(int t)
{
int Fa,Fa2; down(t); // while (!bz[t])
{
Fa=fa[t]; if (!bz[Fa])
{
Fa2=fa[Fa]; if (((tr[Fa2][0]==Fa)^(tr[Fa][0]==t))==0)
rot(Fa),rot(t);
else
rot(t),rot(t);
}
else
rot(t);
}
} void access(int t)
{
int ls=0,x=t; while (t)
{
splay(t); bz[tr[t][1]]=1;
bz[ls]=0; tr[t][1]=ls;
up(t); ls=t;
t=fa[t];
}
splay(x);
} void moveroot(int t)
{
access(t);
rev[t]=1;
} void link(int x,int y)
{
moveroot(x);
fa[x]=y;
} void cut(int x,int y)
{
moveroot(x);
access(y);
splay(x); tr[x][1]=0;
bz[y]=1;
fa[y]=0; up(x);
} int main()
{
freopen("graph.in","r",stdin);
freopen("graph.out","w",stdout); memset(bz,1,sizeof(bz)); scanf("%d%d%d%d",&n,&A,&B,&Q);len=n;
a[0].s=-2133333333;
fo(i,1,A) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].s);
fo(i,1,B) scanf("%d%d%d",&b[i].x,&b[i].y,&b[i].s);
fo(i,1,Q)
{
scanf("%d",&q[i].x);
q[i].id=i;
} sort(q+1,q+Q+1,Cmp); fo(i,1,n)
{
Tr[i][0]=-2133333333;
Tr[i][1]=0;
TR[i]=0; Fa[i]=i;
} sort(a+1,a+A+1,cmp);
sort(b+1,b+B+1,cmp); fo(i,1,A)
if (gf(a[i].x)!=gf(a[i].y))
{
Fa[Fa[a[i].x]]=Fa[a[i].y]; a2[i]=++len;
Tr[len][0]=a[i].s;
Tr[len][1]=i;
TR[len]=i; link(len,a[i].x);
link(len,a[i].y); sum+=a[i].s;
} fo(i,1,n)
Fa[i]=i; fo(i,1,B)
if (gf(b[i].x)!=gf(b[i].y))
{
Fa[Fa[b[i].x]]=Fa[b[i].y]; moveroot(b[i].x);
access(b[i].y); if (Tr[b[i].y][1])
{
j=Tr[b[i].y][1]; cut(a[j].x,a2[j]);
cut(a[j].y,a2[j]); ++len;
Tr[len][0]=-2133333333;
Tr[len][1]=0;
TR[len]=0; link(len,b[i].x);
link(len,b[i].y); ++N;
c[N].x=(b[i].s-a[j].s)/2.0;
c[N].s=b[i].s-a[j].s;
}
} sort(c+1,c+N+1,CMP); j=0;
fo(i,1,Q)
{
while (j<N && q[i].x>=c[j+1].x)
++j,sum+=c[j].s; ans[q[i].id]=sum+(long long)q[i].x*((n-1)-j-j);
} fo(i,1,Q)
printf("%lld\n",ans[i]); fclose(stdin);
fclose(stdout); return 0;
}

5433. 【NOIP2017提高A组集训10.28】图的更多相关文章

  1. 5432. 【NOIP2017提高A组集训10.28】三元组

    题目 题目大意 给你\(X+Y+Z\)个三元组\((x_i,y_i,z_i)\). 然后选\(X\)个\(x_i\),选\(Y\)个\(y_i\),选\(Z\)个\(z_i\). 每个三元组只能选择其 ...

  2. 【JZOJ5428】【NOIP2017提高A组集训10.27】查询

    题目 给出一个长度为n的序列a[] 给出q组询问,每组询问形如\(<x,y>\),求a序列的所有区间中,数字x的出现次数与数字y的出现次数相同的区间有多少个. 分析 我们可以维护一个前缀和 ...

  3. 【JZOJ5439】【NOIP2017提高A组集训10.31】Calculate

    题目 分析 对于\[\sum_{i=1}^{n}\lfloor\dfrac{T-B_i}{A_i}\rfloor\] 我们考虑拆开处理,得到 \[\sum_{i=1}^{n}(\lfloor\dfra ...

  4. 【JZOJ5430】【NOIP2017提高A组集训10.27】图

    题目 有一个n个点的无向图,给出m条边,每条边的信息形如\(<x,y,c,r>\) 给出q组询问形如\(<u,v,l,r>\) 接下来解释询问以及边的意义 询问表示,一开始你在 ...

  5. [JZOJ 5437] [NOIP2017提高A组集训10.31] Sequence 解题报告 (KMP)

    题目链接: http://172.16.0.132/senior/#main/show/5437 题目: 题解: 发现满足上述性质并且仅当A序列的子序列的差分序列与B序列的差分序列相同 于是我们把A变 ...

  6. 【JZOJ5434】【NOIP2017提高A组集训10.30】Matrix

    题目 分析 假设答案为ans, 发现\[k=\sum_{i=1}^{min(n,k)}\lfloor \dfrac{ans}{i} \rfloor\] 于是可以对ans进行二分, 用分块来求出上面的式 ...

  7. 【NOIP2017提高A组集训10.21】Fantasy

    题目 Y sera 陷入了沉睡,幻境中它梦到一个长度为N 的序列{Ai}. 对于这个序列的每一个子串,定义其幻境值为这个子串的和,现在Y sera 希望选择K 个不同的子串并使得这K 个子串的幻境值之 ...

  8. 【NOIP2017提高A组模拟10.7】Adore

    题目 小w 偶然间见到了一个DAG. 这个DAG 有m 层,第一层只有一个源点,最后一层只有一个汇点,剩下的每一层都有k 个节点. 现在小w 每次可以取反第i(1 < i < n - 1) ...

  9. NOIP2017提高A组模拟10.6】Biology

    题目 trie 暴力就是对于每个询问的T个字符串 第i个和第i+1个直接个从后暴力枚举每位是否相同, 但这个方法TLE 我们考虑是否可以用更快的方法来求出两个字符串的最长公共后缀. 我们把所有的字符串 ...

随机推荐

  1. visual studio 的 code snippet(代码片段)

    visual studio自带代码片段,用了6年visual studio才知道有这么个玩意……惭愧 最简单例子 for循环,for,连点两下tab……自己研究吧

  2. eclipse code recommenders cannot download its model repository index

    Cent OS 7 运行 eclipse oxygen 代码提示出现标题所示的错误,解决办法,将网络提供程序设置为手动即可解决. Window->Preference->General-& ...

  3. 转:【开源必备】常用git命令

    原文:https://zhuanlan.zhihu.com/p/25868120 [开源必备]常用git命令 [已重置]   如今在技术领域,码农们习惯了开源,也离不开免费开源的代码,轻松获取代码,不 ...

  4. Java课堂疑问解答与思考3

    一. 两对整数明明完全一样,为何一个输出true,一个输出false? 答: 整数在小于127时都可以用常量池,因此第一次比较的的地址是取自同一个地址的数字,而第二次比较的数是创建了两个不同地址的对象 ...

  5. 【Qt开发】V4L2 API详解 Camera详细设置

    Camera的可设置项极多,V4L2 支持了不少.但Sam之前对这些设置的用法和涵义都是在看videodev2.h中边看边理解,感觉非常生涩.直到写这篇blog时,才发现v4l2有专门的SPEC来说明 ...

  6. CVE 2019 0708 安装重启之后 可能造成 手动IP地址丢失.

    1. 最近两天发现 更新了微软的CVE 2019-0708的补丁之后 之前设置的手动ip地址会变成 自动获取, 造成ip地址丢失.. 我昨天遇到两个, 今天同事又遇到一个.微软做补丁也不走心啊..

  7. [转帖]JVM内存结构 VS Java内存模型 VS Java对象模型

    JVM内存结构 VS Java内存模型 VS Java对象模型 https://www.hollischuang.com/archives/2509 Java作为一种面向对象的,跨平台语言,其对象.内 ...

  8. 基于TCP和UDP的socket

    为什么学习socket 你自己现在完全可以写一些小程序了,但是前面的学习和练习,我们写的代码都是在自己的电脑上运行的,虽然我们学过了模块引入,文件引入import等等,我可以在程序中获取到另一个文件的 ...

  9. anconda下安装opencv

    提示:如果你安装了python其它版本,或者在anaconda中创建了虚拟环境,应该先激活你的环境,然后再在命令窗口执行下面的操作 1.首先下载所需镜像文件: 我们需要上网站去下载我们需要的版本. 官 ...

  10. Consul服务发现在windows下简单使用

    目录 基本介绍: 服务连接: 客户端: 系列章节: 回到顶部 基本介绍: 安装: 下载地址:https://www.consul.io/downloads.html 运行: consul agent ...