ACM选手进阶指北:一个好的代码库与latex维护代码文档

一个好的代码库是必须的,打的久的人心里自然有b数

而且对于算法模板而言,简单的文件夹分级维护就能满足所有需求了

当然,好的代码库不只是把代码堆进去那么简单,

还需要随用随取,变量名不冲突,风格一致,封装优秀等等

并且每次写题都用自己的板子,不断精进细节

非常推荐使用封装,默认参数,宏定义,有意义的变量名,统一取名习惯和常数名等等

例如主席树的模板代码,直接复制粘贴就能用,也不会和你写了一半的其他代码冲突:

int rt[maxn];//@树根@
class ptree{public:
#define nd node[now]
#define ndp node[pre]
#define mid (s+t)/2
    int cnt;
    struct segnode{int l,r,sum;}node[maxn*30];
    void maketree(int s,int t,int &now=rt[0]){
        now=++cnt;nd={s,t,0};
        if(s==t) return ;
        maketree(s,mid,nd.l); maketree(mid+1,t,nd.r);
    }
    void update(int pos,int val,int s,int t,int &now,int pre){
        now=++cnt;nd=ndp;nd.sum+=val;
        if(s==t) return ;
        if(pos<=mid) update(pos,val,s,mid,nd.l,ndp.l);
        else update(pos,val,mid+1,t,nd.r,ndp.r);
    }
    ll query(int l,int r,int s,int t,int now,int pre){
        if(l<=s&&r>=t) return nd.sum-ndp.sum;
        ll sum=0;
        if(l<=mid) sum+=query(l,r,s,mid,nd.l,ndp.l);
        if(r>mid) sum+=query(l,r,mid+1,t,nd.r,ndp.r);
        return sum;
    }
#undef mid
}tree;

再比如重链剖分的模板,用了默认参数,也写了一点注释,用的时候只需要改update和query就行了:

class graph{public://@按点@
  struct node{int to,next;}e[maxn<<1];
  int head[maxn],nume,mp[maxn];
  inline void add(int a,int b){
    e[++nume]={b,head[a]};
    head[a]=nume;
  }
  int ltop[maxn],fa[maxn],deep[maxn];
  int sz[maxn],remp[maxn];
  int son[maxn],cnt;
  void init(int n){rep(i,1,n) head[i]=0;cnt=0,nume=1;}
  void dfs1(int now=1,int pre=1,int d=0){
    deep[now]=d,fa[now]=pre,sz[now]=1,son[now]=0;
    forn(i,now){
      int to=e[i].to;
      if(to!=pre) {
        dfs1(to,now,d+1);
        sz[now]+=sz[to];
        if(sz[to]>sz[son[now]]) son[now]=to;
      }
    }
  }
  void dfs2(int now=1,int pre=1,int sp=1){
    ltop[now]=sp;mp[now]=++cnt;remp[cnt]=now;
      if(son[now])  dfs2(son[now],now,sp);
      forn(i,now){
        int to=e[i].to;
        if(to!=son[now]&&to!=pre) dfs2(to,now,to);
      }
  }
  void getchain(){dfs1();dfs2();}
  int lca(int x,int y){
    for(;ltop[x]!=ltop[y];deep[ltop[x]]>deep[ltop[y]]?x=fa[ltop[x]]:y=fa[ltop[y]]);
    return deep[x]<deep[y]?x:y;
  }//@基础部分@
  void update(int a,int b,int val){
    while(ltop[a]!=ltop[b]){
        if(deep[ltop[a]]<deep[ltop[b]])swap(a,b);
        tree.update(mp[ltop[a]],mp[a],val);
        a=fa[ltop[a]];
    }
      if(deep[a]>deep[b])swap(a,b);
      tree.update(mp[a],mp[b],val);
  }
  int query(int a,int b,int k){
    int sum=0;
    while(ltop[a]!=ltop[b]){
        if(deep[ltop[a]]<deep[ltop[b]])swap(a,b);
        sum+=tree.query(mp[ltop[a]],mp[a],k);
        a=fa[ltop[a]];
    }
      if(deep[a]>deep[b])swap(a,b);
      sum+=tree.query(mp[a],mp[b],k);
      return sum;
  }
}g;
 

而且,分清楚算法的不同区域是很重要的,例如基础线段树的板子:

class segtree{public:
#define nd node[now]
#define ndl node[now<<1]
#define ndr node[now<<1|1]
  struct segnode{
    int l,r,val,tag;
    void update(int x){val+=x,tag+=x;}
  }node[maxn<<2|3];
  int n;
  void pushup(int now){nd.val=min(ndl.val,ndr.val);}
  void pushdown(int now){
    if(nd.tag){
      ndl.update(nd.tag);
      ndr.update(nd.tag);
      nd.tag=0;
    }
  }
  void maketree(int s,int t,int now=1){
    nd={s,t,a[s]};
    if(s==t) return ;
    maketree(s,(s+t)>>1,now<<1);
    maketree(((s+t)>>1)+1,t,now<<1|1);
    pushup(now);
  }
  void update(int s,int t,int x,int now=1){
    if(s<=nd.l&&t>=nd.r) {nd.update(x);return ;}
    pushdown(now);
    if(s<ndr.l) update(s,t,x,now<<1);
    if(t>ndl.r) update(s,t,x,now<<1|1);
    pushup(now);
  }
  int query(int s,int t,int now=1){
    if(s<=nd.l&&t>=nd.r) return nd.val;/
    pushdown(now);
    int ret=1e9;
    if(s<ndr.l) ret=query(s,t,now<<1);
    if(t>ndl.r) ret=min(query(s,t,now<<1|1),ret);
    return ret;
  }
}tree;

对于这份模板,修改成区间+,区间覆盖,区间01翻转等等都非常直接:改2个push,和node内的信息即可,而且想开几棵树就开几棵树

还有一些其他的代码习惯,比如

我所有的树状数据结构,板子里的类名虽然都不一样,比如线段树segtree,树状数组bit等等,

但是我板子里的变量名都是tree,并且接口也都是maketree,update,query等等,然后其他算法,比如树链剖分,也是如此

第二步,就是比赛的实际应用了

很多时候,你都会随时修改你的代码仓库,但是你经常又有比赛,难道每次比赛都去强行弄一个word吗?

显然不需要,考虑你现在已经有一个目录,分门别类的存好了所有的代码,

那么,如果有一个程序,可以每次一键帮我把代码拿出来组合成一个可以直接打印的pdf该多好?

答案是有的,那就是$latex$

是用内嵌代码文件功能,并且用目录索引快速定位!

1.每次添加入新的模板时,只需要在$latex$源修改添加subsection即可

2.每次改旧的模板时,完全不需要改$latex$代码

只需要在需要用的时候,编译一遍$latex$源代码就行

我的基本设置是这样的:

减小行距,段距,减小了页边距,增加了stl关键字+下划线,并使用横版a4大小,三栏,显示行号,制表符2格大小,

代码内嵌中文使用了逃逸符号,用‘@‘将cpp文件内的汉字包起来即可

并且最终双面打印,这样展开看的更多,比赛的时候可以不用经常翻页

不会latex? 学就是啦, 比python写脚本简单多了!

一劳永逸,latex一时爽,一直latex一直爽!

参考:

LaTeX快速入门指南

论文写作的又一利器:VSCode + Latex Workshop + MikTex

论文杀器LaTeX用法汇总(3)——实战·ACM代码模板

如何安装MiKTeX

配置VSCode 作为LaTex 编辑器

Latex中文utf-8编码的三种方式

Latex插入代码并高亮显示

配置默认设置的时候,按[ctrl+‘,‘]进入设置,

然后在整体设置下面修改json,在大括号里加入上面的latex配置就行,注意json的语法,别忘了逗号..



初步的效果如下:



latex源代码如下,我自己非常满意,想用可以直接套我的设置,

用miktex+vscode可以顺利编译:

  1 \documentclass[UTF8]{ctexart}
  2 \usepackage{ctex}
  3 \usepackage{multicol}
  4 \usepackage[landscape,margin=10mm,bottom=5mm,left=5mm,right=5mm,headsep=2mm]{geometry}
  5 \usepackage[breaklinks,colorlinks,linkcolor=black,citecolor=black,urlcolor=black]{hyperref}
  6 \usepackage{graphicx}
  7 \usepackage[Glenn]{fncychap}
  8 \usepackage{listings}
  9 \usepackage{verbatim}
 10 \usepackage{CJKutf8}
 11 \usepackage{textcomp}
 12 \usepackage{xcolor}
 13 \usepackage{setspace}
 14 \usepackage{fancyhdr}
 15 \usepackage{titlesec}
 16 \usepackage{multicol}
 17 \usepackage{CJKutf8}
 18 \geometry{footskip=5mm}
 19 \title{ACM Standard Code Library}
 20 \author{Nervendings NWU-ACMICPC QQ:419000977}
 21 \definecolor{dkgreen}{rgb}{0,0.6,0}
 22 \definecolor{gray}{rgb}{0.5,0.5,0.5}
 23 \definecolor{mauve}{rgb}{0.58,0,0.82}
 24 \definecolor{green2}{rgb}{0,0.6,0.4}
 25 \definecolor{CPPLight}  {HTML} {686868}
 26 \definecolor{CPPSteel}  {HTML} {888888}
 27 \definecolor{CPPDark}   {HTML} {262626}
 28 \definecolor{CPPBlue}   {HTML} {4172A3}
 29 \definecolor{CPPGreen}  {HTML} {487818}
 30 \definecolor{CPPBrown}  {HTML} {A07040}
 31 \definecolor{CPPRed}    {HTML} {AD4D3A}
 32 \definecolor{CPPViolet} {HTML} {7040A0}
 33 \definecolor{CPPGray}  {HTML} {B8B8B8}
 34 \pagestyle{fancy}
 35 \lhead{CUMTB}
 36 \lhead{\CJKfamily{hei} northwest university}
 37 \chead{}
 38 \rhead{Page \thepage}
 39 \rhead{\CJKfamily{hei} Page \thepage}
 40 \lfoot{}
 41 \cfoot{}
 42 \rfoot{}
 43 \setlength{\columnsep}{10pt}
 44 \renewcommand{\headrulewidth}{0.4pt}
 45 \renewcommand{\footrulewidth}{0.4pt}
 46 \setlength{\parskip}{0pt}
 47 \setlength{\lineskip}{1pt}
 48 \titlespacing{\section} {0pt}{0pt}{0pt}
 49 \titlespacing{\subsection} {0pt}{0pt}{2pt}
 50 \lstset{frame=tb,
 51   language=c++,
 52   aboveskip=0pt,
 53   belowskip=0pt,
 54   showstringspaces=false,
 55   columns=flexible,
 56   basicstyle={\ttfamily},
 57   numbers=left,
 58   numberstyle=\small,
 59   keywordstyle=\color[RGB]{40,40,255}\bfseries\underbar,
 60   commentstyle=\it\color[RGB]{0,96,96},
 61   stringstyle=\rmfamily\slshape\color[RGB]{128,0,0},
 62   breaklines=true,
 63   tabsize=2,
 64   frame=single,
 65   numberblanklines=false,
 66   numbersep=5pt,
 67   escapeinside=@@,
 68   xleftmargin=5pt,xrightmargin=5pt,
 69   framexleftmargin=1pt,framexrightmargin=0pt,
 70   captionpos=t,
 71   breaklines=true,
 72   morekeywords={alignas,continute,friend,register,true,alignof,decltype,goto,
 73     reinterpret_cast,try,asm,defult,if,return,typedef,auto,delete,inline,short,
 74     typeid,bool,do,int,signed,typename,break,double,long,sizeof,union,case,
 75     dynamic_cast,mutable,static,unsigned,catch,else,namespace,static_assert,using,
 76     char,enum,new,static_cast,virtual,char16_t,char32_t,explict,noexcept,struct,
 77     void,export,nullptr,switch,volatile,class,extern,operator,template,wchar_t,
 78     const,false,private,this,while,constexpr,float,protected,thread_local,
 79     const_cast,for,public,throw,std},
 80     emph={map,set,multimap,multiset,unordered_map,unordered_set,
 81     unordered_multiset,unordered_multimap,vector,string,list,deque,
 82     array,stack,forwared_list,iostream,memory,shared_ptr,unique_ptr,
 83     random,bitset,ostream,istream,cout,cin,endl,move,default_random_engine,
 84     uniform_int_distribution,iterator,algorithm,functional,bing,numeric,},
 85     emphstyle=\color{CPPViolet}\underbar,
 86 }
 87 \begin{document}
 88 \begin{CJK}{UTF8}{<font>}
 89 \begin{multicols}{3}
 90 \begin{spacing}{0.80}
 91 \begin{titlepage}
 92 \maketitle
 93 \thispagestyle{empty}
 94 \pagebreak
 95 \pagestyle{plain}
 96 \tableofcontents
 97 \end{titlepage}
 98 \section{DataStruct}
 99 \subsection{动态开点线段树}
100 \lstinputlisting{DataStruct/dynamic-segtree-1.cpp}
101 \subsection{区间第k大}
102 \lstinputlisting{DataStruct/kth.cpp}
103 \subsection{线段树优化建图}
104 \lstinputlisting{DataStruct/segtree-graph.cpp}
105 \subsection{线段树合并}
106 \lstinputlisting{DataStruct/segtree-merge.cpp}
107 \subsection{二维线段树}
108 \lstinputlisting{DataStruct/xysegtree.cpp}
109 \subsection{主席树}
110 \lstinputlisting{DataStruct/psegtree.cpp}
111 \subsection{Splay}
112 \lstinputlisting{DataStruct/SplayTree.cpp}
113 \subsection{Treap}
114 \lstinputlisting{DataStruct/treap.cpp}
115 \subsection{老司机树}
116 \lstinputlisting{DataStruct/ODT.cpp}
117 \subsection{可持久化01字典树}
118 \lstinputlisting{DataStruct/p-01trie.cpp}
119 \subsection{并查集非递归+按秩合并}
120 \lstinputlisting{DataStruct/ufs-2.cpp}
121 \subsection{并查集可删除版}
122 \lstinputlisting{DataStruct/ufs.cpp}
123 \subsection{ST表}
124 \lstinputlisting{DataStruct/s-table.cpp}
125 \subsection{扫描线算法}
126 \lstinputlisting{DataStruct/scanline-algorithm.cpp}
127 \subsection{树状数组}
128 \lstinputlisting{DataStruct/bit.cpp}
129 \section{Graph}
130 \subsection{最大流Dinic算法}
131 \lstinputlisting{Graph/dinic.cpp}
132 \subsection{费用流原始对偶算法}
133 \lstinputlisting{Graph/mncf-dij.cpp}
134 \subsection{费用流EK+spfa算法}
135 \lstinputlisting{Graph/mncf-spfa.cpp}
136 \subsection{Tarjan 求桥}
137 \lstinputlisting{Graph/tarjan-bridge.cpp}
138 \subsection{Tarjan 求割顶}
139 \lstinputlisting{Graph/tarjan-point.cpp}
140 \subsection{Dijkstra最短路}
141 \lstinputlisting{Graph/dij.cpp}
142 \subsection{重链剖分}
143 \lstinputlisting{Graph/Heavy-chain-subdivision-edge.cpp}
144 \subsection{欧拉路径}
145 \lstinputlisting{Graph/euler-path.cpp}
146 \subsection{三元环计数}
147 \lstinputlisting{Graph/3-circle.cpp}
148 \subsection{最小生成树Prim算法}
149 \lstinputlisting{Graph/prim.cpp}
150 \subsection{SW全局最小割算法}
151 \lstinputlisting{Graph/Stoer-Wagner.cpp}
152 \subsection{树上点分治}
153 \lstinputlisting{Graph/tree-v-div.cpp}
154 \section{Geometry}
155 \subsection{计算几何}
156 \lstinputlisting{Geometry/basic.cpp}
157 \section{Math}
158 \subsection{逆元,快速幂,快速乘}
159 \lstinputlisting{Math/math-bass.cpp}
160 \subsection{欧拉函数}
161 \lstinputlisting{Math/euler_phi.cpp}
162 \subsection{欧拉函数2}
163 \lstinputlisting{Math/euler.cpp}
164 \subsection{莫比乌斯函数}
165 \lstinputlisting{Math/mobius.cpp}
166 \subsection{米勒罗宾素数判定}
167 \lstinputlisting{Math/Miller-Rabin.cpp}
168 \subsection{大整数因子分解}
169 \lstinputlisting{Math/Pollard-Rho.cpp}
170 \subsection{拉格朗日插值}
171 \lstinputlisting{Math/polysum.cpp}
172 \subsection{异或线性基}
173 \lstinputlisting{Math/linear-bass.cpp}
174 \subsection{线段树维护区间线性基}
175 \lstinputlisting{Math/segtree-linearbass.cpp}
176 \section{String}
177 \subsection{KMP}
178 \lstinputlisting{String/kmp.cpp}
179 \section{Others}
180 \subsection{快速读写}
181 \lstinputlisting{Others/fastio.cpp}
182 \subsection{LIS}
183 \lstinputlisting{Others/lis.cpp}
184 \subsection{矩阵}
185 \lstinputlisting{Others/matrix_pow.cpp}
186 \subsection{头文件}
187 \lstinputlisting{Others/head.cpp}
188 \subsection{莫队算法}
189 \lstinputlisting{Others/mo-algorithm.cpp}
190 \end{spacing}
191 \end{multicols}
192 \end{CJK}
193 \end{document}

原文地址:https://www.cnblogs.com/nervendnig/p/10915584.html

时间: 2024-10-01 04:42:33

ACM选手进阶指北:一个好的代码库与latex维护代码文档的相关文章

Markdown 标记语言指北 - 源码

这是上一篇博客的源代码. 这是班刊约稿的一篇文章. 全文约6000字, 预计需要 60 分钟读完. # Markdown 标记语言指北 #### TOC 1. [什么是 Markdown?](#%E4%BB%80%E4%B9%88%E6%98%AF-Markdown) 1. [Markdown 可以用来干什么?](#Markdown-%E5%8F%AF%E4%BB%A5%E7%94%A8%E6%9D%A5%E5%B9%B2%E4%BB%80%E4%B9%88) 1. [第一步?](#%E7%AC

webpack 最佳配置指北

webpack 最佳配置指北 前言 对于入门选手来讲,webpack 配置项很多很重,如何快速配置一个可用于线上环境的 webpack 就是一件值得思考的事情.其实熟悉 webpack 之后会发现很简单,基础的配置可以分为以下几个方面: entry . output . mode . resolve . module . optimization . plugin . source map . performance 等,本文就来重点分析下这些部分. 内附一张 webpack 零配置对比图片,关

Apache OFBiz指北1-概述

Apache ofbiz是Apache Open for Business的简写,顾名思义,这是一个开源的商业业务系统,项目的最新版本是12.04. 说起这个项目,用过的人(包括我在内)多半都是又爱又恨,爱是因为它为这个项目的核心内容非常的丰富,从前端销售,如网店,目录管理,内容管理:到后端的业务系统,订单,库存,采购,物流,制造(这个功能我没有用过,不熟悉)等:以及企业管理的一些模块,如财务,绩效,协作等.这些基本上把一个销售型企业的常见业务都囊括了.项目自己也实现了一套开发框架,如果是一个初

[转] iOS开发者的Weex伪最佳实践指北

[From] http://www.cocoachina.com/ios/20170601/19404.html 引子 这篇文章是笔者近期关于Weex在iOS端的一些研究和实践心得,和大家一起分享分享,也算是对学习成果的总结.文章里面提到的做法也许不是最佳实践,也许里面的方法称不算是一份标准的指南手册,所以标题就只好叫"伪最佳实践指北"了.有更好的方法欢迎大家一起留言讨论,一起学习. 由于笔者不太了解Android,所以以下的文章不会涉及到Android. 一. React Nativ

【转载】vi/vim使用进阶: 指随意动,移动如飞 (一)

vi/vim使用进阶: 指随意动,移动如飞 (一) << 返回vim使用进阶: 目录 本节所用命令的帮助入口: :help usr_03.txt :help motion.txt :help usr_29.txt :help scroll.txt vim提供的移动方式多如牛毛,但我们并不需要掌握全部这些命令,只需要掌握最适合自己的那些命令.因为我们最终的目的,并不是成为一个vim高手,而是更高效的编辑文本. 我们下面介绍的命令,如果没有特别说明,都是在Normal模式下使用的命令. 这些命令的

【转载】vi/vim使用进阶: 指随意动,移动如飞 (二)

本节所用命令的帮助入口: :help usr_03.txt :help motion.txt :help usr_29.txt :help scroll.txt :help folding 上一篇文章中我们介绍了一些常用的移动命令,本篇将继续介绍更多的命令,使你在文档中自由穿梭. [ 利用跳转表 ] 在vim中,很多命令可以引起跳转,vim会记住把跳转前光标的位置记录到跳转表中,并提供了一些命令来根据跳转表进行跳转.要知道哪些命令引起跳转,参见”:help jump-motions“. 使用命令

中文文案排版指北

中文文案排版指北 統一中文文案.排版的相關用法,降低團隊成員之間的溝通成本,增強網站氣質. Other languages: English Chinese Traditional Chinese Simplifed 目次 空格 中英文之間需要增加空格 中文與數字之間需要增加空格 數字與單位之間需要增加空格 全形標點與其他字符之間不加空格 -ms-text-autospace to the rescue? 標點符號 不重複使用標點符號 全形和半形 使用全形中文標點 數字使用半形字符 遇到完整的英

Android 内存分析指北

android 内存泄漏分析指北 简单来说内存泄漏就是当对象不再被应用程序使用,但是垃圾回收器却不能移除它们,因为它们正在被引用 java 垃圾回收介绍: Java 虚拟机运行所管理的内存包括以下几个运行时的数据区域 如下图: 程序计数器: 一块比较小的内存区域,可以看作是当前线程所执行的字节码的行号指示器.且每个线程都有一个独立的程序计数器. java 虚拟机栈: 线程私有的,描述的是java 方法执行的内存模型,每个线程执行的时候都会创建一个栈帧用于储存 局部变量.操作数栈.动态链接.方法出

VMware Workstation 安装以及Linux虚拟机安装 指北

最近有挺多小伙伴跟我说起虚拟机这个东西,所以,今天就给大家写一篇虚拟机安装使用指北吧. 虚拟机(英语:virtual machine),在计算机科学中的体系结构里,是指一种特殊的软件,可以在计算机平台和终端用户之间创建一种环境,而终端用户则是基于这个软件所创建的环境来操作软件.(该段说明来自wiki) 我们即将安装的软件 VMware 则是系统虚拟机.可以轻松在一个操作系统上面安装多一个或者多个操作系统,如kali.Ubuntu.centos等Linux,windows系统,甚至Mac系统都可以