码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2019-05-24 09:13:30      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:ctr   algo   poll   shared   update   习惯   ati   distrib   定义   

一个好的代码库是必须的,打的久的人心里自然有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}
View Code

 

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

标签:ctr   algo   poll   shared   update   习惯   ati   distrib   定义   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!