tot

[题解]NOI2018 归程

梦想与她 提交于 2019-12-02 15:43:55
传送门 咕了好多天了,先是打了离线暴力,后来学克鲁斯卡尔重构树,然后又咕了好久才打完 题目描述 一张 \(n\) 个点, \(m\) 条边的无向图,每条边有一个长度 \(l\) 和一个海拔 \(a\) ,每天会有一个水位线, \(a\) 小于等于水位线的都会被淹没 \(Q\) 个询问: 询问 \(u,p\) :问从 \(u\) 开始走没被淹没的边所能到达的点中,离1号点的最小距离 强制在线 分析 发现把题目转换过来之后好像还真的是个板子题 先考虑离线做法: 从高到低枚举水位线,对于当前的水位线,如果一条道路目前不会被淹没,那么之后也不会被淹没,那么我们可以用并查集维护相互之间走没有被淹没的路可以到达的点集,同一个点集中的点到1要走的路就是点集中的点到1的最小距离 再考虑强制在线: 先跑一遍最短路求出每个点到 \(1\) 的最短距离这个很显然了 可以发现首先需要维护从每个点开始走 \(a\) 值大于 \(p\) 的边所能到达的点,这个可以用克鲁斯卡尔重构树: 按照 \(a\) 从大到构建重构树,那么两个点的 \(LCA\) 就是他们之间最小海拔的最大值,也就是说,不管怎么走,从 \(u\) 到 \(v\) 必然会经过一条海拔小于等于 \(val[LCA(u,v)]\) 的边,那么我们只需要在克鲁斯卡尔重构树上维护每一个点的子树中的所有点到1的距离的最小值。 查询的时候从 \(u\)

【刷题】【最短路】新年好

久未见 提交于 2019-12-01 07:59:05
重庆城里有n个车站,m条双向公路连接其中的某些站。每两个车站最多用一条公路直接相连,从任何一个车站出发都可以经过一条或多条公路到达其它车站,但不同的路径需要花费的时间可能不同。在一条路径上花费的时间等于路径上所有公路需要的时间和。 佳佳的家在车站1,他有五个亲戚,分别住在车站a、b、c、d、e。过年了,他需要从自己的家出发,拜访每个亲戚(顺序任意),给他们送去节日的祝福。怎样走,才需要最少的时间? 用最短路算法,求出5个点分别的距离,和1到五个点的距离, 然后枚举完事 #include<cstdio> #include<cstdlib> #include<cstring> #include<queue> using namespace std; int n,m; const int N=5e4+3,M=1e5+3; int tot,head[N]; struct node { int v,w,nx; }e[M<<1]; void add(int u,int v,int w) { e[++tot].v =v,e[tot].w =w,e[tot].nx =head[u],head[u]=tot; e[++tot].v =u,e[tot].w =w,e[tot].nx =head[v],head[v]=tot; } inline int read() { int x=0;char c

【JZOJ6357】小ω的图【并查集】

余生长醉 提交于 2019-11-30 04:27:50
题目大意: 题目链接: https://jzoj.net/senior/#main/show/6357 求点1到点 n n n 的最大与路径。 思路: 吧每一条边的距离看成二进制。 显然如果存在一条二进制下最高位为第 k k k 位为1的路径,那么最高位为第 k + 1 k+1 k + 1 位的路径都没有这条路径优秀。 所以我们考虑按二进制下每一位来看。从高位到低位枚举,然后再枚举每一条边,如果这条边的这一位为1,那么就把这条边所连接的两个点划分到一个集合内。 如果最终点1和点 n n n 再一个集合内,那么说明可以,就把所有边权这一位为0的边标记一下,以后就不找了。然后 a n s ∣ = 2 i ans|=2^i a n s ∣ = 2 i 。 时间复杂度 O ( n log ⁡ ( a ) ) O(n\log(a)) O ( n lo g ( a ) ) 代码: # include <cstdio> # include <string> # include <cstring> using namespace std ; typedef long long ll ; const int N = 100010 , M = 500010 ; int n , m , tot , father [ N ] , head [ N ] ; ll ans ; struct edge {

多个串的最长公共子串 SPOJ - LCS2 后缀自动机

∥☆過路亽.° 提交于 2019-11-30 02:01:31
题意: 求多个串的最长公共子串 这里用的是O(n)的后缀自动机写法 我后缀数组的专题有nlog(n)写法的 题解: 对于其中的一个串建立后缀自动机 然后对于后缀自动机上面的每一个节点求出每一个节点最长可以匹配的子串(用maxx【】数组存下) 但是在后缀自动机上面有些节点没有走过,但是是某些走过的点的父亲节点因此也是有值的 for (int i = tot; i; i--) maxx[fail[i]] = max(maxx[fail[i]], min(len[fail[i]], maxx[i]));然后求一个所有最小值里面的最大值就好了 1 #include <set> 2 #include <map> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <ctime> 7 #include <cstdio> 8 #include <string> 9 #include <vector> 10 #include <cstring> 11 #include <iostream> 12 #include <algorithm> 13 #include <unordered_map> 14 15 #define pi acos(-1.0) 16 #define eps 1e-9 17 #define fi

BZOJ 3551: [ONTAK2010]Peaks加强版 Kruskal重构树+dfs序+主席树+倍增

亡梦爱人 提交于 2019-11-28 21:47:47
Code: #include <cstdio> #include <algorithm> #define N 200005 #define M 500002 #define inf 1000000000 #define setIO(s) freopen(s".in","r",stdin) using namespace std; namespace IO { char *p1,*p2,buf[100000]; #define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++) int rd() {int x=0; char c=nc(); while(c<48) c=nc(); while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc(); return x;} }; int h[N],rt[N],n,m,Q; struct Edge { int u,v,c; }e[M]; bool cmp(Edge a,Edge b) { return a.c<b.c; } namespace seg { #define ls t[now].lson #define rs t[now].rson struct Node { int lson,rson,sum; }t[N*30];

P1041 传染病控制

巧了我就是萌 提交于 2019-11-28 17:47:28
https://www.luogu.org/problem/P1041 #include<bits/stdc++.h> using namespace std; #define int long long #define sc(x) scanf("%lld",&x); const int maxn = 1000; int n,m,tot=1,ans=5000; int c[maxn]; vector<int>son[maxn]; int G[maxn][maxn]; void dfs(int i,int fa) { for(int j=1; j<=n; j++) { int x=G[i][j]; //cout<<i<<' '<<fa<<'\n'; if(x!=0) { x=j; // cout<<i<<" zenmehuishi "<<x<<'\n'; if(x!=fa) { son[i].push_back(x); dfs(x,i); } } } } void solve(int p) { bool f=0; if(ans<=tot) return; for(int i=1; i<=n; i++) { if(c[i]==p) { for(int j=0; j<son[i].size(); j++) { f=1; tot++; c[son[i][j]]=p+1; } } } tot

hdu第九场多校

廉价感情. 提交于 2019-11-28 04:53:27
02:线段树两次扫描 #include<bits/stdc++.h> #include<vector> using namespace std; #define maxn 300005 struct Line{int x,y;char s[10];}a[maxn]; int n,m,K; int cmp1(Line &a,Line &b){return a.y<b.y;} int cmp2(Line &a,Line &b){return a.y>b.y;} int x[maxn],tot; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 int lazy[maxn<<2]; void pushdown(int rt){ if(lazy[rt]){ lazy[rt<<1]+=lazy[rt]; lazy[rt<<1|1]+=lazy[rt]; lazy[rt]=0; } } void build(int l,int r,int rt){memset(lazy,0,sizeof lazy);} void update(int L,int R,int val,int l,int r,int rt){ if(L<=l && R>=r){ lazy[rt]++;return; } int m=l+r>>1; pushdown(rt); if

CDQ分治

和自甴很熟 提交于 2019-11-26 14:28:32
学习链接 OI Wiki UntilDawn知乎 BZOJ1935 园丁的烦恼 思路 对于每个查询查分成四个分别进行计数。三维分别为时间、 \(x\) 、 \(y\) ,分治时间,归并 \(x\) ,树状数组 \(y\) 。 代码 #include <set> #include <map> #include <deque> #include <queue> #include <stack> #include <cmath> #include <ctime> #include <bitset> #include <cstdio> #include <string> #include <vector> #include <cassert> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; typedef pair<LL, LL> pLL; typedef pair<LL, int> pLi; typedef pair<int, LL> pil;; typedef pair<int, int> pii; typedef unsigned long long uLL; #define lson rt