cstring

搜索:DLX算法

拈花ヽ惹草 提交于 2020-12-05 04:18:43
精确覆盖问题:在一个0-1矩阵中,选定部分行,使得每一列都有且只有一个1。求解一种选法 舞蹈链(Dance Link),也就是一个循环十字链表,可以快速的删掉和恢复某行某列 结合了舞蹈链的搜索就称作DLX算法 这里贴一个用DLX算法解决16×16数独的代码 9×9的直接暴力会更好 1 // LA2659 Sudoku 2 // Rujia Liu 3 #include<cstdio> 4 #include<cstring> 5 #include<vector> 6 7 using namespace std; 8 9 const int maxr = 5000 ; 10 const int maxn = 2000 ; 11 const int maxnode = 20000 ; 12 13 // 行编号从1开始,列编号为1~n,结点0是表头结点; 结点1~n是各列顶部的虚拟结点 14 struct DLX { 15 int n, sz; // 列数,结点总数 16 int S[maxn]; // 各列结点数 17 18 int row[maxnode], col[maxnode]; // 各结点行列编号 19 int L[maxnode], R[maxnode], U[maxnode], D[maxnode]; // 十字链表 20 21 int ansd, ans[maxr];

「PKUSC2018」神仙的游戏

筅森魡賤 提交于 2020-12-04 14:01:59
由于day2在考场上错误的先开了T3,导致T2只打满了暴力。。。T1暴力都没打满。。。 最后T3虽然想出了正解却因为计算几何的某些细节不会处理而gg掉了(平时不学计算几何活该gg),只得了20分。。。 于是只有132分,被大众分虐暴QWQWQWQWQWQ 其实T2的正解只要想到了 最后一个部分分就差不多会做啦。。。。 由于一个1和0 位移差的绝对值的 所以约数的位移差 的border 都不可行,所以正着的[ s[i] == '1' ] 和 倒着的 [ s[i] == '0' ] 卷一下,就可以判断哪些位移是可行的(不考虑被倍数覆盖的),然后再一个调和级数考虑倍数覆盖就好啦。。。 至于卷积写个FFT就ojbk了,注意eps不要开太小。。。不然会gg #include<cstdio> #include<cstdlib> #include<algorithm> #include<ctime> #include<iostream> #include<complex> #include<cmath> #include<cstring> #define ll long long #define D double #define E complex<double> using namespace std; const int maxn=1100005; const D eps=1e-6,pi

LCA ST表

落花浮王杯 提交于 2020-12-02 07:05:21
// LCA // ST表 在线 #include<iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <algorithm> #define maxn 500001 using namespace std; int n,m,cnt,root,head[maxn],depth[maxn]; int order[ 2 *maxn],first[maxn]; // order[x]dfs中第x次遍历的点(重复) first[x]记录点x在dfs中首次遍历顺序(不重复) int lg[ 2 *maxn],f[ 2 *maxn][ 21 ]; // lg[x]记录log2x的向下取整值 f[x][k]表示包含x点共2^k个点中最小值 struct uio{ int next,to; }edge[ 2 * maxn]; void add( int x, int y) { edge[ ++cnt].next= head[x]; edge[cnt].to = y; head[x] = cnt; } void dfs( int x, int pre) // pre为上次遍历过节点 防止走重 { order[ ++cnt]= x; first[x] = cnt; for

CTSC2017密钥、吉夫特

試著忘記壹切 提交于 2020-11-30 23:36:56
自己是有多么sb。 密钥 大家都说这是一道普及-的题,一年前我做不起,我可以说我太弱啦,我就普及组水平,今年我还是做不起…… 看大佬题解都是:开个桶就好啦! 我:你在说什么…… 首先把环拉成链,倍长。 如果确定$i$这个位置是起始位置,那么特征值就是$\sum\limits_{j=1}^{n-1} (p_j!=0 , sum(A_{i+1}...A_{i+j})>0) $。 那么我们先记录一个前缀和,后面所提到的$A$都是前缀和。$\sum\limits_{j=1}^{n-1} (p_j!=0 , A_{i+j} > A_{i})$。 我们可以这样来考虑,我们把$A$看作高度,从左到右连起来看成折线,我每次在$A_{i}$高度处拉根线,比线高的,并且向上走的(就是p!=0),的折线的个数就是特征值 因为$A_i-A_{i-1}$要么是1要么是-1,所以我们每次减掉或者加上某一个取值的个数就可以了,所以这就是开个桶的意义。 然后如果$p!=0$是B的位置的时候,如果图不变,相当于比线低的,往下走的,的折线的个数,就是特征值, 然后因为折线起始点和终止点的高度都是拉的这根线的高度, 所以 比线低的,往下走的 ,和比线低或者相等的,往上走的,是可以一一对应的,数目是相等的, 而 比线低或者相等的,往上走的 个数,就是k- 比线高的,并且向上走的个数 我在说啥…… //Serene

BJWC2018上学路线

我怕爱的太早我们不能终老 提交于 2020-11-29 20:16:40
题目描述 小B 所在的城市的道路构成了一个方形网格,它的西南角为(0,0),东北角为(N,M)。 小B 家住在西南角,学校在东北角。现在有T 个路口进行施工,小B 不能通过这些路口。小B 喜欢走最短的路径到达目的地,因此他每天上学时都只会向东或北行走;而小B又喜欢走不同的路径,因此他问你按照他走最短路径的规则,他可以选择的不同的上学路线有多少条。由于答案可能很大,所以小B 只需要让你求出路径数mod P 的值。 输入输出格式 输入格式: 第一行为四个整数N、M、T、P。 接下来的T 行,每行两个整数,表示施工的路口的坐标。 输出格式: 一行一个整数,表示路径数mod P 的值。 此题涉及到的数论知识有很多:扩展欧几里得算法、卢卡斯定理(组合数)、中国剩余定理(合并)。 当没有施工点时,答案即C(n+m,m)。 当有施工点时,考虑到j点能影响到i点当且仅当x[i]>=x[j]且y[i]>=y[j]时。影响的路径条数为f[i]=f[i]-f[j]*C(a[i].x-a[j].x+a[i].y-a[j].y,a[i].x-a[j].x),它的解释为:到j点的路径条数乘上j点到i点的路径条数。我们把所有符合条件的j都减去(思考一下这样为什么不会重复减去)。计算之前先sort一遍就可以了,对于取模,卢卡斯定理计算就好了。 但模数不是质数的情况,中国剩余定理合并即可。 Code

SDOI 2017 天才黑客

懵懂的女人 提交于 2020-11-29 16:00:45
/* 根据claris的 博客以及 beginend 的博客来写的 首先考虑如何求出最短路 可以从样例看出 路径是从边走到边的, 所以我们将边看作点 有共同端点的两边之间 互相连边, 边权为lcp。 这条边自己的花费计算要拆点, 拆成的两个点之间连原来的花费 这样跑最短路就可以啦 然而这样的做法有问题, 考虑边数最大可能是M^2切要求M^2个lca 显然不行 这里采用claris巨佬的方法 /*********beginend的题解******* 假如现在有n个节点a[1..n]要两两求lca,我们将其按dfs序排序,设h[i]=dep[lca(a[i],a[i+1])],根据后缀数组height数组的性质不难得到dep[lca(a[i],a[j])]=min(h[i]..h[j-1])。 那么我们可以枚举中间的每个h[i],i两边的点就可以至少花费h[i]的费用来互相访问。我们只要建立前缀虚点和后缀虚电来优化连边即刻。 */ #include <cstdio> #include <algorithm> #include <cstring> #include <queue> #include <iostream> #define M 100200 #define ll long long #define id1(x) x * 2 - 1 #define id2(x) x * 2

[CTSC2018]暴力写挂

蓝咒 提交于 2020-11-27 06:29:04
题目描述 www.lydsy.com/JudgeOnline/upload/201805/day1(1).pdf 题解 首先来看这个我们要最大化的东西。 deep[u]+deep[v]-deep[lca(u,v)]-deep[lca(u',v')] 后面的那个东西看起来不太合群,我们可以把前后拆开。 deep[u]+deep[v]-deep[lca(u,v)] 我们发现这其实就是u到根的链和v到根的链的并。 然后它还等于 (deep[u]+deep[v]+dis[u][v])/2 因为deep数组我们可以直接求出,所以我们就把一颗有根树上的问题放到了无根树上,也就是可以去掉lca的影响了。 然后考虑枚举第二颗树的LCA,那么一组合法的点应当在这个点的两颗不同的子树中。 然后对第一棵树边分,发现这颗边分树也是一颗二叉树,每个叶子结点代表原树上的一个点。 于是这题的做法来了,我们在dfs第二颗树的时候,像线段树合并一样合并边分树,因为不管叶子的情况下,每个节点都代表一条边,每条边连接着两个点。 这样我们对这个点记一个lans和rans分别代表左端点的最优答案和右端点的最优答案。 维护答案的形式为 deep[x]+dis(x,edge) 合并的时候顺带计算答案。 注意,要考虑u和v重合的情况。 代码 #include<iostream> #include <cstdio>

NOI2013部分题解

元气小坏坏 提交于 2020-11-27 04:51:35
Day 1 T1:向量内积 直接暴力有60。发现将n个向量合成$n\times d$的矩阵$A$,然后求$A\times A^T$,得到的矩阵包含了所有的答案。 先考虑$k=2$,将答案矩阵和全1矩阵比较,为0的地方就是答案。 回忆一个十分经典的问题:判断$A\times B$是否与$C$相等。 先随机一个行向量v,若$v\times(A\times B)=v\times A \times B\neq v\times C$,则直接返回$false$。多次随机,成功率为$1-(\frac12)^{times}$。 这种随机化算法通常用于:某对命题充分性和必要性仅具备一个,所以多做几次判定就能提高正确率。$Miller-Rabin$算法就是一个典型的例子。 回到这道题,应用lych的话: 假设对于i,我们求出i之前的所有向量与i的点积的和;如果所有的点积都>0 即=1,那么显然点积的和对二取模=(i-1)%2;否则如果≠(i-1)%2,显然i与i前面的某一个向量的点积=0,我们O(ND)寻找答案即可。但 是这样不一定能得到解,我们不妨随机打乱向量的顺序然后判断,这样至少是1-(1/2)^5的正确率了。 问题在3怎么做,因为不为0可能意味着为1或2,不能确定答案,但是发现在模意义下$1^2\equiv 2^2 (mod 3)$。所以只要平方一下就好了。 1 #include<cstdio

Codeforces 1240B. Sequence Sorting

半腔热情 提交于 2020-11-26 04:11:01
传送门 分析题目发现如果把某个数 $x$ 往左移,那么之后所有小于 $x$ 的数也都要往左移 如果把 $x$ 往右移,那么之后所有大于 $x$ 的数也都要往右移 考虑我们首先一定有一个操作 $n$ 次的合法方案 但是发现其实有些数可以不用操作,只要把比它小的和比它大的搞成合法就行了 发现其实不用操作的数的排名一定是连续的一段,证明可以这样考虑 假设排名不是连续的一段,那么两段中间一定有一个数 $x$ 要操作,那么所有大于 $x$ 数或者小于 $x$ 的数一定要操作 那么矛盾,证明完成 那么现在只考虑排名连续的数最长不用操作的值的数量 显然只要这些数出现的最左边和最右边的区间互不相交那么一定可以不用操作 并且一旦相交就必须操作,所以直接从左到右枚举即可 #include<iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; typedef long long ll; inline int read() { int x= 0 ,f= 1 ; char ch= getchar(); while (ch< ' 0 ' ||ch> ' 9 ' ) { if (ch== ' - ' ) f=- 1 ; ch= getchar(); }

MFC单文档

笑着哭i 提交于 2020-11-24 20:07:26
一、创建并运行MFC单文档程序 1、创建单文档程序 这里使用的是VS2017。首先,打开VS2017,选择文件->新建->项目,然后选择Visual C++ -> MFC /ATL>MFC应用程序 ,如下图所示: 修改名称(或默认),修改位置(或默认),点击确定。然后接下来可以看到如下界面: 应用程序类型选择“单个文档”,其他设置默认,然后点击完成即可创建成功。 2、运行单文档程序 点击"本地Windows调试器"或者使用Ctrl+F5即可运行,得到视图窗口,如下图所示: 二、工作区 1、资源管理器 可以看到屏幕右侧自带了资源管理器,用来管理各类代码。 若没有或不慎关闭,可以从资源->解决方案资源管理器打开。 2、资源视图 资源视图,用于管理程序运行时的视图。 可从视图 ->其他窗口 -> 资源视图,或者快捷键ctrl+shift+E打开。 3、类视图 类视图用于将视图对应的不同请求方式以类中的不同方法来区别定义。 可从视图 -> 类视图,或者快捷键ctrl+shift+C打开。 三、添加菜单及相应事件 1、新建菜单 打开资源视图,点击进入IDR_MAINFRAME,如下所示: 然后在“帮助( H )”后面的空白框中(即箭头所指处)填入新建菜单的名字,然后点击其子菜单处的空白方框,同样写入新建子菜单的名字,如下所示: 2、添加事件 首先,修改子菜单的ID(默认亦可),单击子菜单