vis

P4149 [IOI2011]Race 点分治

对着背影说爱祢 提交于 2019-11-29 01:37:55
思路: 点分治 提交:5次 题解: 刚开始用排序+双指针写的,但是调了一晚上,总是有两个点过不了,第二天发现原因是排序时的 \(cmp\) 函数写错了:如果对于路径长度相同的,我们从小往大按边数排序,当双指针出现 \(==k\) 时,即我们应先左移右指针,否则答案可能会变劣(仔细想一想);若反着排序,应该先右移左指针。 #include<bits/stdc++.h> #define R register int using namespace std; namespace Luitaryi { template<class I> inline I g(I& x) { x=0; register I f=1; register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f; do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*=f; } const int N=2e5+10,Inf=1e+9; int n,K,cnt,sum,rt,tot,ans=N; bool vis[N]; int vr[N<<1],nxt[N<<1],fir[N],w[N<<1],sz[N],d[N],f[N],b[N],mx[N],mem[N]; inline void add(int

P2993 [FJOI2014]最短路径树问题

雨燕双飞 提交于 2019-11-29 01:37:45
思路:最短路+点分治 提交:2次 错因:更新桶的时候没有重置,而直接加上了。 题解: 对于构建最短路树,我们可以先跑最短路,然后dfs一遍连边。 然后就是点分治了,还是一些桶,存点数为 \(x\) 的最长路径的条数。记得更新路径长度时桶要清零。 代码 #include<cstdio> #include<iostream> #include<cstring> #include<queue> #include<algorithm> #define R register int using namespace std; namespace Luitaryi { template<class I> inline I g(I& x) { x=0; register I f=1; register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f; do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*=f; } const int N=30010,M=60010,Inf=0x3f3f3f3f; int n,m,K,rt,tot,cnt,size,sum,ans=-1,C; bool vis[N]; int vr[N<<1],nxt[N<<1],fir[N],w[N<<1]

来自yuzan1830的挑战(三)

只谈情不闲聊 提交于 2019-11-29 00:49:14
社会我赞哥 说在前面 虽然最近有些自闭,但是该来的总是要来的。 yuzan1830给出了一个 n × n n\times n n × n 的网格,每个格子内填了 [ 1 , n 2 ] [1,n^2] [ 1 , n 2 ] 内的一个数字,且每个数字恰好被填一次。现在有两种类型的操作可以进行: 任选一个数字,再从上下左右与它相邻的数字中选一个,两个数字进行交换。即两个数字所在的行数相差 1 1 1 、列数相同,或列数相差 1 1 1 、行数相同。 任选一个数字,再从左上、左下、右上、右下与它相邻的数字中选一个,两个数字进行交换。即两个数字所在的行数和列数都相差 1 1 1 。 为了增加难度,yuzan1830规定每一次操作不能和上一次操作属于同一种类型,即两种操作必须交替进行。而第一次操作可以从两种类型中任选一种。 现在需要让网格中的数字从上到下、从左到右按 1 , 2 , … , n 2 1,2,\dots,n^2 1 , 2 , … , n 2 的顺序排列,求所需的最少步数,并输出任意一种方案。输出的第 i i i 行应包括第 i i i 次操作交换的两个数字。步数为 0 0 0 输出"No Need",无解输出"No Solution"。 样例输入 1 2 9 4 6 3 7 8 5 样例输出 Step #1: 3 9 Step #2: 5 6 Step #3: 6 9

luogu P2764 最小路径覆盖问题

谁都会走 提交于 2019-11-29 00:46:31
题目描述 给定有向图G=(V,E)。设P 是G 的一个简单路(顶点不相交)的集合。如果V 中每个顶点恰好在P 的一条路上,则称P是G 的一个路径覆盖。P 中路径可以从V 的任何一个顶点开始,长度也是任意的,特别地,可以为0。G 的最小路径覆盖是G 的所含路径条数最少的路径覆盖。设计一个有效算法求一个有向无环图G 的最小路径覆盖。 输入输出格式 输入格式: 件第1 行有2个正整数n和m。n是给定有向无环图G 的顶点数,m是G 的边数。接下来的m行,每行有2 个正整数i和j,表示一条有向边(i,j)。 输出格式: 从第1 行开始,每行输出一条路径。文件的最后一行是最少路径数。 输入输出样例 输入样例#1: 11 12 1 2 1 3 1 4 2 5 3 6 4 7 5 8 6 9 7 10 8 11 9 11 10 11 输出样例#1: 1 4 7 10 11 2 5 8 3 6 9 3 题解 先假设每个点是一条路径,那么现在有n条路径。 然后考虑一些路径的合并,显然合并尽可能多的路径可以最小化路径条数。 然后考虑网络流建模,对于每个点拆成两个,连二分图 对于边<u,v>,连< \(u_x,v_y\) >,容量为1 。 对于 \(x\) 的点,连< \(s,x\) >,对于 \(y\) ,连< \(y,t\) >,容量都为1,这样可以保证每一个点只连一条边出去,只有一条边连向它。 这样

Remove Extra One 权值线段树

大憨熊 提交于 2019-11-28 23:07:52
最近疯狂练习线段树。。。 这道题题意很简单,在1-n中,找寻一个数,使得去掉这个数后,对于每个位置中满足 1<=j<i && a[ j ]<a[ i ] 的位置尽可能多。 我们考虑对于每个位置i的贡献,如果当前位置已经满足条件,那么前面任何数的删除,对这个位置实际上是没有贡献的,并且对于当前位置来说,删除这个位置相当于减去一个满足条件的位置。 如果当前位置可以通过删除一个数,变成可能的话,那么这个数字一定在前i位置里,并且只有一个大于这个数的位置,我们可以轻松是查询前i位比某个值大的数目,以及查询最大值所处于的位置(一直往右查询即可)。那么i位置,要想成为答案,就必须删除前面的最大值,我们删除前面最大值,相当于增加一个满足条件的位置。 如果前面有两个以上大于这个数,这个数肯定不能成为答案。 所以我们维护一个数组,这个数组vis[i]代表删除i,可以生成新的满足条件位置个数,取最大值中,值最小的。就是答案!!! 维护用权值线段树就可以啦!!! 1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #include<algorithm> 5 #define LL long long 6 #define lson rt<<1 7 #define rson rt<<1|1 8 #include<vector> 9

[学习笔记]启发式分治

喜夏-厌秋 提交于 2019-11-28 23:05:51
启发式分治 给定 n 个数,求满足某种条件的点对数目或最大权值,而这个最大权值与点对( a , b )的区间[ a , b ]的区间最大/最小值有关。 那么这时就可以考虑分治,对于区间[ L , R ],找到最小/大值所在位置,然后处理横跨最小/大值所在位置的点对,然后递归处理子区间。 HUD-Make Rounddog Happy 求有多少区间,满足其中每个数都不同,并且区间最大值大于k 预处理区间最大值,以及每个数往左往右最远不相同的位置 暴力处理区间小的,然后递归 #pragma GCC optimize(2) #include <bits/stdc++.h> #define ll long long using namespace std; const int maxn = 3e5 + 7; int stmax[maxn][20], pos[maxn][20], poww[20], logg[maxn]; int n, s[maxn], p, L[maxn], R[maxn]; bool vis[maxn]; void get_st() { poww[0] = 1; for (int i = 1; i < 20; ++i) poww[i] = poww[i - 1] << 1; for (int i = 2; i <= n; ++i) logg[i] = logg[i >>

[笔记]点分治

一笑奈何 提交于 2019-11-28 22:47:25
基本思路:点分治,是一种针对 可带权树上简单路径统计问题 的算法。对于一个节点,只解决经过这棵子树的根节点的路径,对于子节点问题下推子树。 //当初的主要问题是vis[]在干什么qwq,终于知道了 #include<iostream> #include<cstdio> #include<algorithm> #define R register int using namespace std; #define ull unsigned long long #define ll long long #define pause (for(R i=1;i<=10000000000;++i)) #define In freopen("NOIPAK++.in","r",stdin) #define Out freopen("out.out","w",stdout) namespace Fread { static char B[1<<15],*S=B,*D=B; #ifndef JACK #define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++) #endif inline int g() { R ret=0,fix=1; register char ch; while(!isdigit(ch

AC自动机 POI2000病毒

独自空忆成欢 提交于 2019-11-28 22:21:19
题目链接: https://www.luogu.org/problem/P2444 题意:给你一些字符串,问能不能找到一个无限长的字符串,使得给定的这些字符串不会出现在该无限长字符串中 一般我们写ac自动机都是尽可能的使多匹配,而本题反其道而行,要尽可能的不匹配,那么我们可以遇到fail标记就跳(因为一个字符串的标记是在最后,中途就调走了肯定就不会遇到了)。如果存在一个无限长的字符串,那么我们内部肯定会形成一个环,且这个环中不会有带结束标记的点,且这个环一定要包含根节点。 PS:这题数据量非常小,我自己想过数据量大了可以结合拓扑排序,但入度不是指向fail边的起点,而是终点,这样可以从小的更新大的,但最后拓扑排序fake了,我做不出来,只能用题解方法了。 #include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=30007; const int inf=0x3f3f3f3f; const int N=1e7; const ll mod=998244353; #define meminf(a) memset(a,0x3f,sizeof(a)) #define mem0(a) memset(a,0,sizeof(a)) char a[maxn]; struct node{ int

素数筛选

限于喜欢 提交于 2019-11-28 22:10:25
简单的引入一下欧拉函数 素数筛选知道4种,暴力筛(逐个判断),埃拉特斯特尼筛 ,欧拉线性筛 ,一个大于5的素数一定在6的倍数周围(PS:不知道官方名是什么) 埃拉特斯特尼筛法。时间复杂度为O(n loglog n) //倍数筛除 时间复杂度(o(nloglogn) //一个素数的倍数一定不是素数 int vis[1000] , prime[1000]; void judge() { memset(vis,1,sizeof(vis)); int cnt=0; prime[0] = prime[1] = 0; for(int i=2;i<1000;i++) { if(vis[i]) { prime[cnt++] = i; //cout<<prime[cnt-1]<<endl; for(int j=i*i;j<1000;j+=i) vis[j] = 0; } } } 欧拉线性筛法 时间复杂度(o(n) ) //欧拉线性筛法 时间复杂度(o(n)) const int MAXN=3000001; int prime[MAXN];//保存素数 bool vis[MAXN];//初始化 void Prime(int n) { int cnt=0; memset(vis,1,sizeof(vis)); for(int i=2;i<=n;i++) { if(vis[i]) { prime[cnt+

正睿培训day1考试

馋奶兔 提交于 2019-11-28 21:50:59
链接 A 理解一下题意,然后玩几组样例就能发现,实际上就是 \(k\) 个 \(i\) 等价于 \(1\) 个 \(i-1\) 。所以就类似于 \(k\) 进制进行进位,如果最后 \(0\) 位上不是 \(0\) ,那么就存在划分方案。否则就不存在划分方案。 输出第一次划分方案就记录一下每个数字是不是后面的数字凑出来的。如果是的话就像后面数字连边。这样就形成了一棵 \(k\) 叉树。最后 \(dfs\) 一遍输出即可。 考场上 \(vector\) 下标从1开始记录了。就 \(wa\) 惨了。。。 /* * @Author: wxyww * @Date: 2019-08-04 11:41:21 * @Last Modified time: 2019-08-04 16:08:45 */ #include<cstdio> #include<iostream> #include<cstdlib> #include<cmath> #include<ctime> #include<bitset> #include<cstring> #include<algorithm> #include<string> #include<queue> #include<vector> using namespace std; typedef long long ll; const int N =