首页 > 其他分享 >【NOIP2017提高A组集训10.28】图

【NOIP2017提高A组集训10.28】图

时间:2022-12-26 18:32:46浏览次数:46  
标签:NOIP2017 pfa 10.28 ll mx fa maxn 集训 fo


Description

有一个n个点A+B条边的无向连通图,有一变量x,每条边的权值都是一个关于x的简单多项式,其中有A条边的权值是k+x,另外B条边的权值是k-x,如果只保留权值形如k+x的边,那么这个图仍是一个连通图,如果只保留权值形如k-x的边,这个图也依然是一个连通图。
给出q组询问,每组询问给出x的值,问此时这个无向连通图的最小生成树权值是多少。

Solution

其实这是一道非常套路的题目。
首先我们很显然的要对询问离线处理,然后在x等于无穷小的时候,明显全部都是A树里面的边。然后当x逐渐变大,B树里的边就会逐渐替换掉A树里的边,但是B树的边不会换掉B树的边。
那么我们可以考虑把B树的k从小到大排序,然后逐个替换掉A树中的边,就是用LCT来维护最小生成树,然后算出这条边什么时候会替换掉它,最后把替换掉的时间排一个序,把询问里面的时间离线的搞,求出答案。
但是我们会发现根据时间来说,有可能k比较大的边在k比较小的之间替换掉树中的边,首先假如这构成的环不相交是不会影响的。
但是相交的情况怎么办?
第一种情况是虽然是相交,但是他们取得的环上最大值不在同一个环内,这样是不会影响的。
第二种情况是取得的环上最大值在同一个环类,因为不过先后,在时间线上的形态还是一样的,所以没有影响了。
然后这题就变成了经典的用LCT维护最小生成树的题目。

Code

#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<math.h>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int maxn=6e5+7;
ll i,j,k,l,n,m,ans,A,B,q;
ll an[maxn],f[maxn],u,v,d[maxn],bz[maxn],x,y,pp;
ll t[maxn][2],fa[maxn],mx[maxn],c[maxn],p[maxn],num,pfa[maxn],inf;
struct node{
ll x,y,k,o;
}a[maxn],b[maxn],e[maxn],s[maxn];
bool cmp(node x,node y){return x.k<y.k||x.k==y.k&&x.y<y.y;}
int gf(ll x){return(!f[x])?x:f[x]=gf(f[x]);}
int son(ll x){return t[fa[x]][0]!=x;}
void update(ll x){
ll l=t[x][0],r=t[x][1];mx[0]=-inf;
if(mx[l]>mx[r])mx[x]=mx[l],p[x]=p[l];
else mx[x]=mx[r],p[x]=p[r];
if(c[x]>mx[x])mx[x]=c[x],p[x]=x;
}
void rotate(ll x){
ll y=fa[x],z=son(x);
t[y][z]=t[x][1-z];fa[t[x][1-z]]=y;
t[fa[x]=fa[y]][son(y)]=x;;
if(pfa[y])pfa[x]=pfa[y],pfa[y]=0;
t[fa[y]=x][1-z]=y;
update(y),update(x);
}
ll make(ll x){
if(bz[x]){
swap(t[x][0],t[x][1]);
bz[t[x][0]]^=1,bz[t[x][1]]^=1;bz[x]=0;
}
}
void remove(ll x,ll y){
while(x!=y)d[++d[0]]=x,x=fa[x];
while(d[0])make(d[d[0]--]);
}
void splay(ll x,ll y){
remove(x,y);
while(fa[x]!=y){
if(fa[fa[x]]!=y)if(son(fa[x])==son(x))rotate(fa[x]);else rotate(x);
rotate(x);
}
}
ll access(ll x){
ll y=0;
while(x){
splay(x,0);
pfa[t[x][1]]=x;fa[t[x][1]]=0;
t[fa[y]=x][1]=y;pfa[y]=0;
update(x);
y=x,x=pfa[x];
}
}
void makeroot(ll x){access(x);splay(x,0);bz[x]^=1;}
void link(ll x,ll y){makeroot(y);pfa[y]=x;}
void cut(ll x,ll y){
makeroot(x);access(y);splay(y,0);
t[y][0]=fa[x]=pfa[x]=0;update(y);
}
int main(){
freopen("graph.in","r",stdin);
freopen("graph.out","w",stdout);
scanf("%lld%lld%lld%lld",&n,&A,&B,&q);inf=9999999999999999;
fo(i,1,A)scanf("%lld%lld%lld",&a[i].x,&a[i].y,&a[i].k);
fo(i,1,B)scanf("%lld%lld%lld",&b[i].x,&b[i].y,&b[i].k);
sort(a+1,a+1+A,cmp);sort(b+1,b+1+B,cmp);
fo(i,1,A)c[i+n]=a[i].k;fo(i,1,B)c[n+A+i]=-inf;
fo(i,1,n)c[i]=-inf;
fo(i,1,A){
u=gf(a[i].x),v=gf(a[i].y);
if(u==v)continue;ans+=a[i].k;
m++;f[u]=v;link(a[i].x,n+i);link(n+i,a[i].y);
if(m==n-1)break;
}
e[1].k=-inf;e[num=1].x=0;
fo(i,1,B){
u=b[i].x,v=b[i].y;
if(u==v)continue;
makeroot(u),access(v);splay(v,0);
l=p[v];if(mx[v]==-inf)continue;pp++;if(pp>=n)break;
cut(a[l-n].x,l);cut(l,a[l-n].y);
e[++num].y=b[i].k-a[l-n].k;e[num].x=i;
e[num].k=b[i].k-a[l-n].k;
link(b[i].x,n+A+i);link(n+A+i,b[i].y);
}
sort(e+1,e+1+num,cmp);
fo(i,1,q)scanf("%lld",&s[i].k),s[i].x=i;
sort(s+1,s+1+q,cmp);x=0;pp=n-1;
fo(i,1,q){
while(x+1<=num&&e[x+1].k<=s[i].k*2){
x++,ans+=e[x].y;if(e[x].x)pp--;
}
an[s[i].x]=ans+(2*pp-n+1)*s[i].k;
}
fo(i,1,q)printf("%lld\n",an[i]);
}


标签:NOIP2017,pfa,10.28,ll,mx,fa,maxn,集训,fo
From: https://blog.51cto.com/u_15923198/5970023

相关文章

  • Python DevOps运维开发实战集训营【中级班,第8期,2022年12月结课】
    点击下载——​​PythonDevOps运维开发实战集训营【中级班,第8期,2022年12月结课】​​提取码:as28《PythonDevOps运维开发实战集训营【中级班】》,第8期,2022年12月10号结课......
  • 牛客CSP-S提高组赛前集训营2
    牛客CSP-S提高组赛前集训营2预估得分:100+100+40实际得分:65+80+40不开longlong见祖宗T1服务器需求https://ac.nowcoder.com/acm/contest/1101/A小多计划在接下来......
  • [集训队互测2022]Path 题解
    考虑对于两条路径\(I_i,I_j\)计算可以产生贡献的\(I\)的数量。分类讨论:1.\(I_i,I_j\)端点不相交可以发现\(I_i\subseteqI,I_j\subseteqI\)。对于任意一条路径\(I_i......
  • #6035. 「雅礼集训 2017 Day4」洗衣服
    题目前言这个贪心有点妙,考试的时候没有想出来,一看题解恍然大悟。分析首先对于洗衣服,显而易见我们可以用堆来处理,可以得出每件衣服洗完的时间\(t_i\),其中\(t_i\)表示......
  • 八校杭州集训练习记录
    八校联考杭州集训!清澄内部私有的题目当然不会被计入。不然就是泄题了是不是。这个标题只是表示一段时期。八校集训时间是2022.11.29-12.16,当然今天才开始记录是因......
  • 杭州集训D4T1
    题目简述给定一个大小为\(n\left(n\le10^5\right)\)的环,每个点初始为白色,每一步在所有点中均匀随机选择一个,将其染黑(已经黑则不变);然后对于所有白点,如果其左右都是黑色,那......
  • 2022.10.28 模拟赛小结
    2022.10.28模拟赛小结目录2022.10.28模拟赛小结更好的阅读体验戳此进入赛时思路T1CodeT2T3T4正解T1CodeT2T3T4UPD最惨的一场,基本所有题都挂了,最终得分$20\texttt{pts......
  • 第三章第2节: 2021.10.28 MySQL设计
            定长存储用char例如身份证号    第二点就是业务用到的库就用业务名                 ......
  • [NEFU ACM大一暑假集训 解题报告]字典树
    [NEFUACM大一暑假集训解题报告]字典树题目A-L语言多模式匹配,AC自动机建立Trie图。不过这个题数据量很小,貌似可以暴力建立跳转关系,加上标记处理即可。对于样例的AC自动......
  • [NEFU ACM大一暑假集训 解题报告]前缀和与差分
    [NEFUACM大一暑假集训解题报告]前缀和与差分题量略大,所以解题报告和fjy大佬分了一下工由我负责A-K部分题解(不是AK部分题解啊,哈哈)后半部分题解(LM+R~V+XYZ)由fjy大佬发布......