首页 > 其他分享 >【笔记】P2542 [AHOI2005] 航线规划 答辩做法

【笔记】P2542 [AHOI2005] 航线规划 答辩做法

时间:2023-10-03 20:24:15浏览次数:41  
标签:AHOI2005 200005 int tr P2542 tag low 答辩 define

洛谷上是可以过掉的。NFLSOJ上加强数据,还卡常,所以 90pts。

首先倒着做很好想。对于最终的图,我们可以 tarjan 缩点然后建树,边权为 \(1\),表示一条割边。然后每次连两个点的时候就把树上这一段路径赋值为 \(0\)。查询就是树上路径和。这些操作都可以点赋边权然后树剖来做。所以你就得到了 \(200+\) 行的 \(log^2\) 答辩做法。

我才不会告诉你区间赋 0 pushdown 的时候由于 tag 初始为 0 调了将近 1h

正解有奇怪的单 \(log\) 做法。还有 LCT。不会,咕咕咕。

//If, one day, I finally manage to make my dreams a reality...
//I wonder, will you still be there by my side?
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
#define TIE cin.tie(0),cout.tie(0)
#define int long long
#define y1 cyy
#define fi first
#define se second
#define cnt1(x) __builtin_popcount(x)
#define mk make_pair
#define pb push_back
#define pii pair<int,int>
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
#define lbt(x) (x&(-x))
using namespace std;
int n,m,q;
struct edge{
	int u,v;
}e1[500005];
struct node{
	int c,u,v,ans;
}b[500005]; 
map<pii,bool> mp; 


int head[200005],tot=1,timer,cnt;
int dfn[200005],low[200005],stk[200005],top;
int col[200005];

struct Node{
	int to,nxt;
}e[500005];
void add(int u,int v){
	e[++tot]={v,head[u]};
	head[u]=tot;
}
void tarjan(int x,int fe){
	dfn[x]=low[x]=++timer;
	stk[++top]=x;
	for(int i=head[x];i;i=e[i].nxt){
		int tmp=e[i].to;
		if(!dfn[tmp]){
			tarjan(tmp,i);
			low[x]=min(low[x],low[tmp]);
		}
		else if(i^1^fe){
			low[x]=min(low[x],dfn[tmp]);
		}
	}
	if(dfn[x]==low[x]){
		cnt++;
		do{
			col[stk[top--]]=cnt;
		}while(stk[top+1]!=x);
	}
}


int fa[200005],dep[200005],siz[200005],DFN[200005];
int Timer,Top[200005],son[200005],u,v;
vector<int> a[200005];
struct SGT{
	struct node{
		int l,r,sum,tag;
	}tr[800005];
	void build(int i,int l,int r){
		tr[i].l=l,tr[i].r=r,tr[i].tag=-1;
		if(l==r){
			tr[i].sum=1;
			return ;
		}
		int mid=(l+r)>>1;
		build(ls(i),l,mid),build(rs(i),mid+1,r);
		tr[i].sum=tr[ls(i)].sum+tr[rs(i)].sum;
	}
	void pushdown(int i){
		if(tr[i].tag!=-1){
			tr[ls(i)].tag=tr[i].tag;
			tr[rs(i)].tag=tr[i].tag;
			tr[ls(i)].sum=(tr[ls(i)].r-tr[ls(i)].l+1)*tr[i].tag;
			tr[rs(i)].sum=(tr[rs(i)].r-tr[rs(i)].l+1)*tr[i].tag;
			tr[i].tag=-1;
		}
	}
	void upd(int i,int l,int r,int k){
		if(tr[i].l>=l&&tr[i].r<=r){
			tr[i].sum=(tr[i].r-tr[i].l+1)*k;
			tr[i].tag=k;
			return ;
		}
		pushdown(i);
		int mid=(tr[i].l+tr[i].r)>>1;
		if(l<=mid) upd(ls(i),l,r,k);
		if(mid<r) upd(rs(i),l,r,k);
		tr[i].sum=tr[ls(i)].sum+tr[rs(i)].sum;
	}
	int query(int i,int l,int r){
		if(tr[i].l>=l&&tr[i].r<=r) return tr[i].sum;
		pushdown(i);
		int mid=(tr[i].l+tr[i].r)>>1,ans=0;
		if(l<=mid) ans+=query(ls(i),l,r);
		if(mid<r) ans+=query(rs(i),l,r);
		return ans;
	}
}sgt;

void dfs1(int x,int Fa){   //fa,siz,dep,mxson 
	fa[x]=Fa,siz[x]=1,dep[x]=dep[Fa]+1;
	int mx=-1;
	for(int i=0;i<a[x].size();i++){
		int tmp=a[x][i];
		if(tmp==Fa) continue;
		dfs1(tmp,x),siz[x]+=siz[tmp];
		if(siz[tmp]>mx) mx=siz[tmp],son[x]=tmp;
	}
}
void dfs2(int x,int Fa,int t){   //dfn,top 
	DFN[x]=++Timer;
	Top[x]=t;
	if(!son[x]) return ;
	dfs2(son[x],x,t);
	for(int i=0;i<a[x].size();i++){
		int tmp=a[x][i];
		if(tmp==Fa||tmp==son[x]) continue;
		dfs2(tmp,x,tmp);
	} 
}
int Query(int x,int y){
	int ans=0;
	while(Top[x]!=Top[y]){
		if(dep[Top[x]]<dep[Top[y]]) swap(x,y);
		ans+=sgt.query(1,DFN[Top[x]],DFN[x]);
		x=fa[Top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	ans+=sgt.query(1,DFN[x]+1,DFN[y]);
	return ans;
}
void Upd(int x,int y,int k){
	while(Top[x]!=Top[y]){
		if(dep[Top[x]]<dep[Top[y]]) swap(x,y);
		sgt.upd(1,DFN[Top[x]],DFN[x],k);
		x=fa[Top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
//	cout<<"***"<<DFN[x]+1<<' '<<DFN[y]<<endl; 
	sgt.upd(1,DFN[x]+1,DFN[y],k);
}


signed main(){
//	freopen("lane.in","r",stdin);
//	freopen("lane.out","w",stdout); 
	IOS;TIE;
	cin>>n>>m;
	for(int i=1;i<=m;i++) cin>>e1[i].u>>e1[i].v;
	while(1){
		q++;
		cin>>b[q].c;
		if(b[q].c==-1){
			q--;
			break;
		}
		cin>>b[q].u>>b[q].v;
		if(b[q].c==0){
			mp[mk(b[q].u,b[q].v)]=1;
			mp[mk(b[q].v,b[q].u)]=1;
		}
	}
	
	for(int i=1;i<=m;i++){
		if(!mp[mk(e1[i].u,e1[i].v)]){
			add(e1[i].u,e1[i].v);
			add(e1[i].v,e1[i].u);
		}
	}
	tarjan(1,0);
	
	for(int i=1;i<=m;i++){
		if(!mp[mk(e1[i].u,e1[i].v)]){
			int x=col[e1[i].u],y=col[e1[i].v];
			if(x^y) a[x].pb(y),a[y].pb(x);
		}
	}
	
	dfs1(1,0);
	dfs2(1,0,1);
	sgt.build(1,1,n);
	
//	for(int i=1;i<=n;i++) cout<<col[i]<<' ';
//	cout<<endl;
//	for(int i=1;i<=n;i++) cout<<DFN[col[i]]<<' ';
//	cout<<endl;
	
	for(int i=q;i>=1;i--){
		int x=col[b[i].u],y=col[b[i].v];
		if(b[i].c==1) b[i].ans=Query(x,y);
		else Upd(x,y,0);
//		for(int j=1;j<=n;j++){
//			cout<<sgt.query(1,DFN[col[j]],DFN[col[j]])<<endl;
//		}
	}
	
	for(int i=1;i<=q;i++){
		if(b[i].c==1) cout<<b[i].ans<<'\n';
	}
	return 0;
}


/*
6 6 3
1 2
1 3
3 4
2 4
5 4
3 6
1 5 6
1 1 5
1 5 6
*/

标签:AHOI2005,200005,int,tr,P2542,tag,low,答辩,define
From: https://www.cnblogs.com/binary1110011/p/17741583.html

相关文章

  • 答辩稿子
    主题:大学里面分数至是一部分,应该多分配点时间花在其他有意义的事情上学业成绩:智育rank4, 综测rank2,花30%的时间在智育上, 花60%的时间在我感兴趣的领域因为大学更多的就是提供一个自主发展的平台一个原因:在我看来只要能得到90分就代表你掌握了这门课......
  • 【笔记】P6419 [COCI2014-2015#1] Kamp 答辩做法
    模拟赛T3,用非常答辩的做法过掉了。5k代码写完后竟只调了10分钟首先考虑指定出发点如何算答案。用一眼看出法,就是把出发点也定为必经点后,\(必经点连通距离\times2\-\出发点到某一必经点的最大距离\)。这个想法可以由P9304的思路得到。再有,要求树上所有点的答案,多半是换根......
  • 第三届“泰迪杯”数据分析职业技能大赛: 教育平台的线上课程智能推荐 (决赛候选)答辩P
    ......
  • 10课程设计收尾及优秀作品展示答辩【FPGA模型机课程设计】
    10课程设计收尾及优秀作品展示答辩【FPGA模型机课程设计】前言说明推荐10课程设计收尾及优秀作品展示答辩安排目录一、单周期CPU的设计过程1、基本的20条指令固定指令格式设计I型指令设计J型指令设计lwsw指令设计2、扩展的20条指令J型扩展指令设计乘法除法指令格式3、实现中断异......
  • 答辩准备,知识问题等
    架构和框架的区别框架是一种编程工具,它是一个预定义的结构,包含了一系列的类、函数、方法等,可以帮助开发者快速搭建应用程序,提高开发效率。框架通常提供了一些通用的功能,例如数据库访问、用户认证、会话管理等,开发者可以在此基础上进行二次开发,根据自己的需求进行扩展。架构是一......
  • [AHOI2005]约数研究
    没错,数学也有分类了qaq,我之前学算法的时候妹学数学,今天算是被搞怕了(但还是不听ovo)学会了两种方法,主要思想还是,对于每个i来说,他在从1-n中的贡献值是n/i,也就是1-n中约数含有它的数目是n/i(厉害吧,刚学的)另外一种方法是筛法,说实话这个你应该想到的(恼),不优化会爆的(30分......
  • MCP2542FDT-E/MFVAO符合各种汽车要求,设计用于CAN 2.0和CAN FD网络之间的接口。
    MCP2542FDT-E/MFVAOCANFD收发器设计用作物理总线和CAN协议控制器之间的接口。这些收发器具有适用于CAN协议控制器的差分传输和接收能力。MCP2542CANFD收发器具有出色的环路延迟对称性,可支持面向CANFD的高达8Mbps的数据速率。这些收发器可在高压尖峰和CAN控制器之间提供缓冲。......
  • bzoj1969. [AHOI2005] LANE 航线规划 树链剖分+离线逆向处理删边
    保证了无论怎么破坏航线,图都会是一个连通图也就是说,起码肯定有一棵生成树考虑在生成树上U,V之间加边,会对树上各个点的割边情况产生什么影响对于任意点对(u,v),如果它们之间的最短路径不经过从U到V的树上路径,那是没有影响的否则:关键路径的数目会减少减少了多少?U,V之间树上路径经......
  • 答辩乱做
    发现代码能力太弱了,题目会了也不会写,所以训练。真的好痛苦。代码难度,思维难度被评为\([1,5]\)间的一个实数。loj2018所用时间代码长度思维难度代码难度罚时......
  • PPT 毕业答辩PPT应该怎么样改
    PPT毕业答辩PPT应该怎么样改......