首页 > 其他分享 >LOJ #2842. 「JOISC 2018 Day 4」野猪

LOJ #2842. 「JOISC 2018 Day 4」野猪

时间:2023-01-04 15:22:19浏览次数:73  
标签:MaT LOJ ll 2842 JOISC int using 短路 define

题面传送门

考试的时候只想到处理\(O(1)\)的边没想到维护\(O(1)\)的路径。

首先如果没有可以退一步的限制显然就是相邻两点的最短路之和。退一步的限制想到点边互换。与处理出\(dist_{i,j}\)表示\(i\)号边和\(j\)号边之间的最短路,这里为了方便将其拆成有向边。这个可以用Dij加上双向链表\(O(m^2\log m)\)求出来。

然后考虑两个点之间要维护什么东西。显然需要最短路,如果最短路两端点被前后占了,那么就需要第一条边和最后一条边都不一样,因此要求出第一条边和最后一条边都不一样的最短路。分别记为\((s_1,t_1),(s_2,t_2)\)。如果这中间两个各占了一个也不行,因此还要记录开头不为\(s_1\),结尾不为\(t_2\),以及开头不为\(s_2\),结尾不为\(t_1\)的最短路。维护这四条最短路即可。

修改直接放在线段树上就好了,时间复杂度\(O(m^2\log m+4^2q\log m)\)

code:

#include<bits/stdc++.h>
#define Gc() getchar() 
#define Me(x,y) memset(x,y,sizeof(x))
#define Mc(x,y) memcpy(x,y,sizeof(x))
#define d(x,y) ((m)*(x-1)+(y))
#define R(n) (rnd()%(n))
#define Pc(x) putchar(x)
#define LB lower_bound
#define UB upper_bound
#define PB push_back
using ll=long long;using db=double;using lb=long db;using ui=unsigned;using ull=unsigned ll;
using namespace std;const int N=2e3+5,M=4e5+5,K=1e5+5,mod=1e9+7,Mod=mod-1;const ll INF=1e18+7;const db eps=1e-5;mt19937 rnd(263082);
int n,m,T,L,x,y,z,X[N*2],Y[N*2],Z[N*2],A[M];ll d[N*2][N*2];
struct Edge{int to,w,id;};vector<Edge> S[N];list<int> G[N];
struct MaT{
	int S[4],T[4];ll W[4];MaT(){Me(S,-1);Me(T,-1);Me(W,0x3f);} 
	MaT operator +(const MaT &B)const{
		MaT C;ll Ans=INF;int I1=-1,I2=-1,i,j;
		for(i=0;i<4;i++) for(j=0;j<4;j++) if(T[i]^B.S[j]^1&&W[i]+B.W[j]<Ans) Ans=W[i]+B.W[j],I1=S[i],I2=B.T[j];
		C.S[0]=I1;C.T[0]=I2;C.W[0]=Ans;
		I1=-1;I2=-1;Ans=INF;
		for(i=0;i<4;i++) for(j=0;j<4;j++) if(T[i]^B.S[j]^1&&W[i]+B.W[j]<Ans&&S[i]^C.S[0]&&B.T[j]^C.T[0]) Ans=W[i]+B.W[j],I1=S[i],I2=B.T[j];
		C.S[1]=I1;C.T[1]=I2;C.W[1]=Ans;
		I1=-1;I2=-1;Ans=INF;
		for(i=0;i<4;i++) for(j=0;j<4;j++) if(T[i]^B.S[j]^1&&W[i]+B.W[j]<Ans&&S[i]^C.S[0]&&B.T[j]^C.T[1]) Ans=W[i]+B.W[j],I1=S[i],I2=B.T[j];
		C.S[2]=I1;C.T[2]=I2;C.W[2]=Ans;
		I1=-1;I2=-1;Ans=INF;
		for(i=0;i<4;i++) for(j=0;j<4;j++) if(T[i]^B.S[j]^1&&W[i]+B.W[j]<Ans&&S[i]^C.S[1]&&B.T[j]^C.T[0]) Ans=W[i]+B.W[j],I1=S[i],I2=B.T[j];
		C.S[3]=I1;C.T[3]=I2;C.W[3]=Ans;
		return C;
	}
}Bas[N][N],p,Ans,Cl;
namespace Tree{
	#define ls v<<1
	#define rs v<<1|1
	MaT f[M];void Up(int v){f[v]=f[ls]+f[rs];}
	void BD(int l=1,int r=L-1,int v=1){if(l==r) {f[v]=Bas[A[l]][A[l+1]];return;}int m=l+r>>1;BD(l,m,ls);BD(m+1,r,rs);Up(v);}
	void Ins(int x,MaT y,int l=1,int r=L-1,int v=1){if(l==r) {f[v]=y;return;}int m=l+r>>1;x<=m?Ins(x,y,l,m,ls):Ins(x,y,m+1,r,rs);Up(v);}
	#undef ls
	#undef rs
}
struct Node{int to;ll w;bool operator <(const Node &B)const{return w>B.w;};};priority_queue<Node> Q;
int main(){
	freopen("1.in","r",stdin);
	int i,j;scanf("%d%d%d%d",&n,&m,&T,&L);for(i=1;i<=m;i++) scanf("%d%d%d",&x,&y,&z),X[2*i-2]=x,Y[2*i-2]=y,Z[2*i-2]=Z[2*i-1]=z,X[2*i-1]=y,Y[2*i-1]=x;
	for(i=0;i<2*m;i++) S[X[i]].PB((Edge){Y[i],Z[i],i});
	Me(d,0x3f);for(i=0;i<2*m;i++){
		for(j=1;j<=n;j++) G[j].clear();
		for(j=0;j<2*m;j++) G[X[j]].PB(j);
		Q.push((Node){i,d[i][i]=Z[i]});
		while(!Q.empty()){
			Node x=Q.top();Q.pop();
			for(auto j=G[Y[x.to]].begin();j!=G[Y[x.to]].end();)if(*j^x.to^1){
				if(d[i][x.to]+*j<d[i][*j])Q.push((Node){*j,d[i][*j]=d[i][x.to]+Z[*j]});
				auto p=j;j++;G[Y[x.to]].erase(p);
			}else j++;
		}
	}
	for(i=1;i<=n;i++){
		for(j=1;j<=n;j++)if(i^j){p=Cl;
			for(Edge x:S[i]) for(Edge y:S[j]) d[x.id][y.id^1]<p.W[0]&&(p.W[0]=d[x.id][y.id^1],p.S[0]=x.id,p.T[0]=y.id^1);
			for(Edge x:S[i]) for(Edge y:S[j]) d[x.id][y.id^1]<p.W[1]&&x.id^p.S[0]&&y.id^p.T[0]^1&&(p.W[1]=d[x.id][y.id^1],p.S[1]=x.id,p.T[1]=y.id^1);
			for(Edge x:S[i]) for(Edge y:S[j]) d[x.id][y.id^1]<p.W[2]&&x.id^p.S[0]&&y.id^p.T[1]^1&&(p.W[2]=d[x.id][y.id^1],p.S[2]=x.id,p.T[2]=y.id^1);
			for(Edge x:S[i]) for(Edge y:S[j]) d[x.id][y.id^1]<p.W[3]&&x.id^p.S[1]&&y.id^p.T[0]^1&&(p.W[3]=d[x.id][y.id^1],p.S[3]=x.id,p.T[3]=y.id^1);
			Bas[i][j]=p;
		}
	}
	for(i=1;i<=L;i++) scanf("%d",&A[i]);Tree::BD();
	while(T--){
		scanf("%d%d",&x,&y);A[x]=y;
		if(x^L) Tree::Ins(x,Bas[y][A[x+1]]);
		if(x^1) Tree::Ins(x-1,Bas[A[x-1]][y]);
		printf("%lld\n",Tree::f[1].W[0]<2e17?Tree::f[1].W[0]:-1);
	}
}

标签:MaT,LOJ,ll,2842,JOISC,int,using,短路,define
From: https://www.cnblogs.com/275307894a/p/17024929.html

相关文章

  • nginx-clojure 调试简单试用
    对于nginx-clojure的调试实际上就是基于jdwp参考配置nginx.confjvm_options"-agentlib:jdwp=transport=dt_socket,address=*:909#{pno},server=y,suspend=......
  • nginx-clojure java 集成试用
    主要是基于java开发一个简单的扩展,学习下流程java项目pom.xml<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4......
  • nginx-clojure docker 镜像
    主要是一个测试,方便学习使用nginx-clojure强大的能力dockerfile直接基于了openjdk:10-slim基础镜像,同时基于copy文件的格式处理FROMopenjdk:10-slimWOR......
  • LOJ2399「JOISC 2017 Day 4」绑架 2
    Link题解发现询问次数很少,可以支持单次询问\(O(N+M)\)的做法,这样就可以枚举每条道路然后去做。但直接做貌似不太行,所以先发掘一些性质。假如询问点\((X,Y)\)处在全......
  • nginx-clojure nginx clojure & java & groovy 模块
    nginx-clojure是一个nginx扩展模块,让我们可以直接运行clojure&java&groovy,还是比较强大的,支持的功能也不少我们可以直接基于jvm对于nginx进行扩展了,还是值得尝试......
  • LOJ #2776. 「BalticOI 2018」蠕虫之忧
    题面传送门拼图题/fn首先考虑先搞一个通解出来。考虑一维的情况,显然是二分,设区间\([l,r]\),询问\(mid\)和\(mid+1\)的大小关系,如果\(H_{mid}<H_{mid+1}\),则\([mid+1,r]\)......
  • 【题解】LOJ #6384. 「是男人就过8题——Pony.ai」SignLocation
    题意LOJ#6384.「是男人就过8题——Pony.ai」SignLocation给定\(n\)个整点\(p_1,...,p_n\)以及\(k\)次标记点的机会,定义\(c(i,j)\)为:第\(i\)个整点和第......
  • LOJ 6041 「雅礼集训 2017 Day7」事情的相似度 题解 (SAM+启发式合并)
    题目链接首先很容易想到的是对反串求SA和LCP,然后询问就是求起点在某个区间内的所有后缀两两LCP的最大值,可以用莫队解决,时间复杂度\(O(n\sqrtnlogn)\),应该是过不了的。......
  • 洛谷 P5363 / LOJ #3114 「SDOI2019」移动金币
    洛谷传送门LOJ传送门不错的博弈+计数。不难发现题中的游戏是阶梯Nim的变体。若设\(a_i\)为第\(i\)枚金币的位置,令\(\foralli\in[2,m],\b_i=a_i-a_{i-......
  • Luogu4194 / LOJ115 - 网络流 -
    题目链接:https://www.luogu.com.cn/problem/P4194题解:LOJ115是无源汇上下界可行流的板子题Luogu4194需要一定建模无源汇上下界可行流,需要求一张图的流函数,使得满足流......