• [SDOI2015]道路修建


    不知道为什么之前这篇在博客园上出了一点问题

    链接

    P5618


    题解

    线段树之什么都能维护

    用线段树维护最小生成树。

    和[SHOI2008]堵塞的交通很像,一开始想naive了,以为只需要维护上下联通和不联通的答案,两个联通的合并加上中间小的边。

    但是这样其实假掉了,一组hack是

    7 1
    2 5 9 4 7 2 
    2 10 8 7 7 6 
    8 2 3 10 7 6 8 
    Q 1 7
    

    答案应该是 61,而不是 63。

    把图画出来后发现其实两个联通的合并的时候中间形成了个环,应该从环上减掉最大的,而不能只看中间连接的两条边。

    为了处理这个环,我们需要维护此时一段区间最左/右的竖边及其左/右边的边权最大值。

    然后还有一个问题是如果左/右边只有一条竖边并且被减掉了,那么更新的时候就需要用另一边的信息。为了处理这个问题,需要记录最左/右的竖边权值和区间内竖边总数,以及区间内所有横边的最大值。

    于是我们就可以处理掉这个pushup了

    inline void pushup(node &p,node x,node y){
    	p.L=x.L,p.R=y.R;int mid=x.R,tt=max(uc[mid],dc[mid]);
    	p.maxn=max(tt,max(x.maxn,y.maxn));
    	int t1=max(tt,max(x.maxrr,y.minll)),t=x.con+y.con+uc[mid]+dc[mid]-t1;
    	p.con=t,p.sum=x.sum+y.sum-1;
    	p.minl=x.minl,p.minll=x.minll,p.maxr=y.maxr,p.maxrr=y.maxrr;
    	if(t1!=x.maxr&&t1!=y.minl)p.sum++;
    	if(t1==x.maxr&&x.sum==1)p.minl=y.minl,p.minll=max(tt,max(y.minll,x.maxn));
    	else if(t1==y.minl&&y.sum==1)p.maxr=x.maxr,p.maxrr=max(tt,max(x.maxrr,y.maxn));
    }
    

    然后修改就和[SHOI2008]堵塞的交通一样,查询答案还要简单一些。

    然后就做完了。


    code

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    #define cs const
    #define in read()
    inline int read(){
    	int p=0,f=1;char c=getchar();
    	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    	while(isdigit(c)){p=p*10+c-48;c=getchar();}
    	return p*f;
    }
    cs int N=60005;
    int n,m;
    int uc[N],dc[N],c[N];
    struct node{
    	int con,sum,maxr,minl,maxrr,minll,maxn;
    	int L,R;
    }a[N<<2];
    inline void pushup(node &p,node x,node y){
    	p.L=x.L,p.R=y.R;int mid=x.R,tt=max(uc[mid],dc[mid]);
    	p.maxn=max(tt,max(x.maxn,y.maxn));
    	int t1=max(tt,max(x.maxrr,y.minll)),t=x.con+y.con+uc[mid]+dc[mid]-t1;
    	p.con=t,p.sum=x.sum+y.sum-1;
    	p.minl=x.minl,p.minll=x.minll,p.maxr=y.maxr,p.maxrr=y.maxrr;
    	if(t1!=x.maxr&&t1!=y.minl)p.sum++;
    	if(t1==x.maxr&&x.sum==1)p.minl=y.minl,p.minll=max(tt,max(y.minll,x.maxn));
    	else if(t1==y.minl&&y.sum==1)p.maxr=x.maxr,p.maxrr=max(tt,max(x.maxrr,y.maxn));
    }
    inline void built(int l,int r,int p){
    	if(l==r){a[p].sum=1,a[p].maxn=0,a[p].con=a[p].maxr=a[p].minl=a[p].minll=a[p].maxrr=c[l],a[p].L=a[p].R=l;return ;}
    	int mid=(l+r)>>1;built(l,mid,p<<1),built(mid+1,r,p<<1|1),pushup(a[p],a[p<<1],a[p<<1|1]);
    }
    inline void change1(int l,int r,int p,int x,int d){
    	int mid=(l+r)>>1;
    	if(l==r){a[p].con=a[p].maxr=a[p].minl=a[p].minll=a[p].maxrr=d;return ;}
    	if(x<=mid)change1(l,mid,p<<1,x,d);
    	else change1(mid+1,r,p<<1|1,x,d);
    	pushup(a[p],a[p<<1],a[p<<1|1]);
    }
    inline void change2(int l,int r,int p,int x,int ud,int d){
    	int mid=(l+r)>>1;
    	if(mid==x){
    		if(ud)uc[x]=d;
    		else dc[x]=d;
    		pushup(a[p],a[p<<1],a[p<<1|1]);
    		return ;
    	}
    	if(x<mid)change2(l,mid,p<<1,x,ud,d);
    	else change2(mid+1,r,p<<1|1,x,ud,d);
    	pushup(a[p],a[p<<1],a[p<<1|1]);
    }
    inline node query(int l,int r,int p,int ql,int qr){
    	if(l>=ql&&r<=qr)return a[p];
    	int mid=(l+r)>>1;
    	if(qr<=mid)return query(l,mid,p<<1,ql,qr);
    	if(ql>mid)return query(mid+1,r,p<<1|1,ql,qr);
    	node ans;pushup(ans,query(l,mid,p<<1,ql,qr),query(mid+1,r,p<<1|1,ql,qr));
    	return ans;
    }
    string s;
    int r1,c1,r2,c2,d;
    signed main(){
    	n=in,m=in;
    	for(int i=1;i<n;i++)uc[i]=in;
    	for(int i=1;i<n;i++)dc[i]=in;
    	for(int i=1;i<=n;i++)c[i]=in;
    	built(1,n,1);
    	for(int i=1;i<=m;i++){
    		cin>>s;
    		if(s[0]=='C'){
    			r1=in,c1=in,r2=in,c2=in,d=in;
    			if(c1>c2)swap(c1,c2),swap(r1,r2);
    			if(r1==r2)change2(1,n,1,c1,r1==1,d);
    			else change1(1,n,1,c1,d);
    		}
    		else{
    			c1=in,c2=in;
    			cout<<query(1,n,1,c1,c2).con<<'\n';
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    爬虫时http错误提示
    json.dumps()和json.loads()
    scrapy框架原理学习
    利用tushare进行对兴业银行股价的爬取,并使用numpy进行分析
    随机生成60位同学成绩,并求他们的平均数,中位数,众数等
    numpy中random的使用
    matplotlib中subplot的使用
    使用matplotlib画饼图
    乔坟,乔坟!
    c#控件的动画显示效果
  • 原文地址:https://www.cnblogs.com/llmmkk/p/16047989.html
Copyright © 2020-2023  润新知