<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Template on I'm OWenT</title><link>//owent.net/tags/template.html</link><description>Recent content in Template on I'm OWenT</description><generator>Hugo</generator><language>zh-cn</language><copyright>&lt;a rel="license" href="https://github.com/owent/blog-hugo/blob/master/LICENSE.md"&gt;&lt;img alt="知识共享许可协议" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/80x15.png" /&gt;&lt;/a&gt;</copyright><lastBuildDate>Tue, 03 Jun 2014 20:55:44 +0000</lastBuildDate><atom:link href="//owent.net/tags/template/index.xml" rel="self" type="application/rss+xml"/><item><title>再议 C++ 11 Lambda表达式</title><link>//owent.net/2014/1060.html</link><pubDate>Tue, 03 Jun 2014 20:55:44 +0000</pubDate><guid>//owent.net/2014/1060.html</guid><description>&lt;h2 id="目录"&gt;目录&lt;/h2&gt;&#10;&lt;!-- toc --&gt;&#13;&#10;&lt;h2 id="c-的lambda表达式"&gt;C++ 的Lambda表达式&lt;/h2&gt;&#10;&lt;p&gt;C++ 11 标准发布，各大编译器都开始支持里面的各种新特性，其中一项比较有意思的就是lambda表达式。&lt;/p&gt;&#10;&lt;h2 id="语法规则"&gt;语法规则&lt;/h2&gt;&#10;&lt;p&gt;C++ 11 Lambda表达式的四种声明方式&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&#10;\[ capture \]( params ) mutable(optional) exception attribute -&amp;gt; ret { body }&lt;/li&gt;&#10;&lt;li&gt;&#10;\[ capture \]( params ) -&amp;gt; ret { body }&lt;/li&gt;&#10;&lt;li&gt;&#10;\[ capture \]( params ) { body }&lt;/li&gt;&#10;&lt;li&gt;&#10;\[ capture \]{ body }&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;capture&lt;/strong&gt;是外部引用的参数&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;params&lt;/strong&gt;是函数参数&lt;/li&gt;&#10;&lt;li&gt;后面可以跟一些函数修饰符&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;ret&lt;/strong&gt;是返回值类型，如果不指定，会推断一个类型&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;body&lt;/strong&gt;部分是函数内容&#10;具体用法可以参照&lt;a href="http://en.cppreference.com/w/cpp/language/lambda"&gt;C++文档&lt;/a&gt;，这里就不复述了&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;这四个声明式都会返回一个匿名的&lt;strong&gt;仿函数&lt;/strong&gt;实例）。&#10;这里有一个比较重要的一点，就是他是一个&lt;strong&gt;仿函数&lt;/strong&gt;实例，而不是直接一个&lt;strong&gt;函数&lt;/strong&gt;。&lt;/p&gt;</description></item><item><title>捣鼓一个协程库</title><link>//owent.net/2014/1000.html</link><pubDate>Wed, 05 Mar 2014 21:52:49 +0000</pubDate><guid>//owent.net/2014/1000.html</guid><description>&lt;p&gt;今年准备安安心心写一个协程库。一方面是觉得协程挺有意思，另一方面也是因为C/C++在这方面没有一个非常权威的解决方案。&#10;按照我自己风格还是喜欢C++，所以协程库定名为 libcopp 。&#10;源码托管在 github: &lt;a href="https://github.com/owent/libcopp"&gt;https://github.com/owent/libcopp&lt;/a&gt;&#10;镜像托管 &lt;a href="http://git.oschina.net/owent/distinctionpp"&gt;http://git.oschina.net/owent/distinctionpp&lt;/a&gt;&lt;/p&gt;&#10;&lt;h1 id="首先介绍-什么是协程"&gt;首先介绍: 什么是协程&lt;/h1&gt;&#10;&lt;p&gt;协程(coroutine)，是一种用户态模拟线程的组件。（具体说明参见：&lt;a href="http://zh.wikipedia.org/wiki/%E5%8D%8F%E7%A8%8B"&gt;http://zh.wikipedia.org/wiki/%E5%8D%8F%E7%A8%8B&lt;/a&gt;）&lt;/p&gt;</description></item><item><title>C++11动态模板参数和type_traits</title><link>//owent.net/2014/971.html</link><pubDate>Mon, 27 Jan 2014 16:27:46 +0000</pubDate><guid>//owent.net/2014/971.html</guid><description>&lt;p&gt;C++11标准里有动态模板参数已经是众所周知的事儿了。但是当时还有个主流编译器还不支持。&#10;但是现在，主要的编译器。VC(Windows),GCC(Windows,Linux),Clang(Mac,IOS)都已经支持了。所以就可以准备用于生产环境了。&#10;type_traits没啥好说的。主要是一些静态检测。主要还是要看动态模板参数和他们两的结合使用上。&#10;动态模版参数标准文档见:&#10;&lt;a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2242.pdf"&gt;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2242.pdf&lt;/a&gt;&#10;和&#10;&lt;a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2555.pdf"&gt;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2555.pdf&lt;/a&gt;&#10;虽然贴出来了。估计是没人看得。所以就直接说重点。&lt;/p&gt;</description></item><item><title>std和boost的function与bind实现剖析</title><link>//owent.net/2013/938.html</link><pubDate>Thu, 28 Nov 2013 22:01:30 +0000</pubDate><guid>//owent.net/2013/938.html</guid><description>&lt;!-- toc --&gt;&#13;&#10;&lt;p&gt;用过std和boost的function对象和bind函数的童鞋们都知道这玩意用起来腰不酸了，腿不疼了，心情也舒畅了。先上一个简单得示例：&lt;/p&gt;&#10;&lt;pre&gt;&lt;code class="language-cpp"&gt;std::string str;&#13;&#10;std::function&amp;lt;bool()&amp;gt; func = std::bind(&amp;amp;std::string::at, &amp;amp;str);&#13;&#10;bool is_empty = func();&lt;/code&gt;&lt;/pre&gt;&#13;&#10;&lt;p&gt;但是这是怎么做到的呢？看完源码以后，你会发现这里面有着一些很巧妙的设计。&lt;/p&gt;</description></item><item><title>ACM 计算几何 个人模板</title><link>//owent.net/2010/11.html</link><pubDate>Mon, 04 Oct 2010 11:19:02 +0000</pubDate><guid>//owent.net/2010/11.html</guid><description>&lt;pre&gt;&lt;code class="language-cpp"&gt;/**&#13;&#10; * 二维ACM计算几何模板&#13;&#10; * 注意变量类型更改和EPS&#13;&#10; * #include &amp;lt;cmath&amp;gt;&#13;&#10; * #include &amp;lt;cstdio&amp;gt;&#13;&#10; * By OWenT&#13;&#10; */&#13;&#10;&#13;&#10;const double eps = 1e-8;&#13;&#10;const double pi = std::acos(-1.0);&#13;&#10;//点&#13;&#10;class point&#13;&#10;{&#13;&#10;public:&#13;&#10; double x, y;&#13;&#10; point(){};&#13;&#10; point(double x, double y):x(x),y(y){};&#13;&#10;&#13;&#10; static int xmult(const point &amp;amp;ps, const point &amp;amp;pe, const point &amp;amp;po)&#13;&#10; {&#13;&#10; return (ps.x - po.x) * (pe.y - po.y) - (pe.x - po.x) * (ps.y - po.y);&#13;&#10; }&#13;&#10;&#13;&#10; //相对原点的差乘结果，参数：点[_Off]&#13;&#10; //即由原点和这两个点组成的平行四边形面积&#13;&#10; double operator *(const point &amp;amp;_Off) const&#13;&#10; {&#13;&#10; return x * _Off.y - y * _Off.x;&#13;&#10; }&#13;&#10; //相对偏移&#13;&#10; point operator - (const point &amp;amp;_Off) const&#13;&#10; {&#13;&#10; return point(x - _Off.x, y - _Off.y);&#13;&#10; }&#13;&#10; //点位置相同(double类型)&#13;&#10; bool operator == (const point &amp;amp;_Off) const&#13;&#10; {&#13;&#10; return std::fabs(_Off.x - x) &amp;lt; eps &amp;amp;&amp;amp; std::fabs(_Off.y - y) &amp;lt; eps;&#13;&#10; }&#13;&#10; //点位置不同(double类型)&#13;&#10; bool operator != (const point &amp;amp;_Off) const&#13;&#10; {&#13;&#10; return ((*this) == _Off) == false;&#13;&#10; }&#13;&#10; //两点间距离的平方&#13;&#10; double dis2(const point &amp;amp;_Off) const&#13;&#10; {&#13;&#10; return (x - _Off.x) * (x - _Off.x) &amp;#43; (y - _Off.y) * (y - _Off.y);&#13;&#10; }&#13;&#10; //两点间距离&#13;&#10; double dis(const point &amp;amp;_Off) const&#13;&#10; {&#13;&#10; return std::sqrt((x - _Off.x) * (x - _Off.x) &amp;#43; (y - _Off.y) * (y - _Off.y));&#13;&#10; }&#13;&#10;};&#13;&#10;&#13;&#10;//两点表示的向量&#13;&#10;class pVector&#13;&#10;{&#13;&#10;public:&#13;&#10; point s, e;//两点表示，起点[s]，终点[e]&#13;&#10; double a, b, c;//一般式,ax&amp;#43;by&amp;#43;c=0&#13;&#10;&#13;&#10; pVector(){}&#13;&#10; pVector(const point &amp;amp;s, const point &amp;amp;e):s(s),e(e){}&#13;&#10;&#13;&#10; //向量与点的叉乘,参数：点[_Off]&#13;&#10; //[点相对向量位置判断]&#13;&#10; double operator *(const point &amp;amp;_Off) const&#13;&#10; {&#13;&#10; return (_Off.y - s.y) * (e.x - s.x) - (_Off.x - s.x) * (e.y - s.y);&#13;&#10; }&#13;&#10; //向量与向量的叉乘,参数：向量[_Off]&#13;&#10; double operator *(const pVector &amp;amp;_Off) const&#13;&#10; {&#13;&#10; return (e.x - s.x) * (_Off.e.y - _Off.s.y) - (e.y - s.y) * (_Off.e.x - _Off.s.x);&#13;&#10; }&#13;&#10; //从两点表示转换为一般表示&#13;&#10; bool pton()&#13;&#10; {&#13;&#10; a = s.y - e.y;&#13;&#10; b = e.x - s.x;&#13;&#10; c = s.x * e.y - s.y * e.x;&#13;&#10; return true;&#13;&#10; }&#13;&#10;&#13;&#10; //-----------点和直线（向量）-----------&#13;&#10; //点在向量左边（右边的小于号改成大于号即可,在对应直线上则加上=号）&#13;&#10; //参数：点[_Off],向量[_Ori]&#13;&#10; friend bool operator&amp;lt;(const point &amp;amp;_Off, const pVector &amp;amp;_Ori)&#13;&#10; {&#13;&#10; return (_Ori.e.y - _Ori.s.y) * (_Off.x - _Ori.s.x)&#13;&#10; &amp;lt; (_Off.y - _Ori.s.y) * (_Ori.e.x - _Ori.s.x);&#13;&#10; }&#13;&#10;&#13;&#10; //点在直线上,参数：点[_Off]&#13;&#10; bool lhas(const point &amp;amp;_Off) const&#13;&#10; {&#13;&#10; return std::fabs((*this) * _Off) &amp;lt; eps;&#13;&#10; }&#13;&#10; //点在线段上,参数：点[_Off]&#13;&#10; bool shas(const point &amp;amp;_Off) const&#13;&#10; {&#13;&#10; return lhas(_Off)&#13;&#10; &amp;amp;&amp;amp; _Off.x - std::min(s.x, e.x) &amp;gt; -eps &amp;amp;&amp;amp; _Off.x - std::max(s.x, e.x) &amp;lt; eps&#13;&#10; &amp;amp;&amp;amp; _Off.y - std::min(s.y, e.y) &amp;gt; -eps &amp;amp;&amp;amp; _Off.y - std::max(s.y, e.y) &amp;lt; eps;&#13;&#10; }&#13;&#10;&#13;&#10; //点到直线/线段的距离&#13;&#10; //参数： 点[_Off], 是否是线段[isSegment](默认为直线)&#13;&#10; double dis(const point &amp;amp;_Off, bool isSegment = false)&#13;&#10; {&#13;&#10; //化为一般式&#13;&#10; pton();&#13;&#10;&#13;&#10; //到直线垂足的距离&#13;&#10; double td = (a * _Off.x &amp;#43; b * _Off.y &amp;#43; c) / sqrt(a * a &amp;#43; b * b);&#13;&#10;&#13;&#10; //如果是线段判断垂足&#13;&#10; if(isSegment)&#13;&#10; {&#13;&#10; double xp = (b * b * _Off.x - a * b * _Off.y - a * c) / ( a * a &amp;#43; b * b);&#13;&#10; double yp = (-a * b * _Off.x &amp;#43; a * a * _Off.y - b * c) / (a * a &amp;#43; b * b);&#13;&#10; double xb = std::max(s.x, e.x);&#13;&#10; double yb = std::max(s.y, e.y);&#13;&#10; double xs = s.x &amp;#43; e.x - xb;&#13;&#10; double ys = s.y &amp;#43; e.y - yb;&#13;&#10; if(xp &amp;gt; xb &amp;#43; eps || xp &amp;lt; xs - eps || yp &amp;gt; yb &amp;#43; eps || yp &amp;lt; ys - eps)&#13;&#10; td = std::min(_Off.dis(s), _Off.dis(e));&#13;&#10; }&#13;&#10;&#13;&#10; return fabs(td);&#13;&#10; }&#13;&#10;&#13;&#10; //关于直线对称的点&#13;&#10; point mirror(const point &amp;amp;_Off) const&#13;&#10; {&#13;&#10; //注意先转为一般式&#13;&#10; point ret;&#13;&#10; double d = a * a &amp;#43; b * b;&#13;&#10; ret.x = (b * b * _Off.x - a * a * _Off.x - 2 * a * b * _Off.y - 2 * a * c) / d;&#13;&#10; ret.y = (a * a * _Off.y - b * b * _Off.y - 2 * a * b * _Off.x - 2 * b * c) / d;&#13;&#10; return ret;&#13;&#10; }&#13;&#10; //计算两点的中垂线&#13;&#10; static pVector ppline(const point &amp;amp;_a, const point &amp;amp;_b)&#13;&#10; {&#13;&#10; pVector ret;&#13;&#10; ret.s.x = (_a.x &amp;#43; _b.x) / 2;&#13;&#10; ret.s.y = (_a.y &amp;#43; _b.y) / 2;&#13;&#10; //一般式&#13;&#10; ret.a = _b.x - _a.x;&#13;&#10; ret.b = _b.y - _a.y;&#13;&#10; ret.c = (_a.y - _b.y) * ret.s.y &amp;#43; (_a.x - _b.x) * ret.s.x;&#13;&#10; //两点式&#13;&#10; if(std::fabs(ret.a) &amp;gt; eps)&#13;&#10; {&#13;&#10; ret.e.y = 0.0;&#13;&#10; ret.e.x = - ret.c / ret.a;&#13;&#10; if(ret.e == ret. s)&#13;&#10; {&#13;&#10; ret.e.y = 1e10;&#13;&#10; ret.e.x = - (ret.c - ret.b * ret.e.y) / ret.a;&#13;&#10; }&#13;&#10; }&#13;&#10; else&#13;&#10; {&#13;&#10; ret.e.x = 0.0;&#13;&#10; ret.e.y = - ret.c / ret.b;&#13;&#10; if(ret.e == ret. s)&#13;&#10; {&#13;&#10; ret.e.x = 1e10;&#13;&#10; ret.e.y = - (ret.c - ret.a * ret.e.x) / ret.b;&#13;&#10; }&#13;&#10; }&#13;&#10; return ret;&#13;&#10; }&#13;&#10;&#13;&#10; //------------直线和直线（向量）-------------&#13;&#10; //直线重合,参数：直线向量[_Off]&#13;&#10; bool equal(const pVector &amp;amp;_Off) const&#13;&#10; {&#13;&#10; return lhas(_Off.e) &amp;amp;&amp;amp; lhas(_Off.s);&#13;&#10; }&#13;&#10; //直线平行，参数：直线向量[_Off]&#13;&#10; bool parallel(const pVector &amp;amp;_Off) const&#13;&#10; {&#13;&#10; return std::fabs((*this) * _Off) &amp;lt; eps;&#13;&#10; }&#13;&#10; //两直线交点，参数：目标直线[_Off]&#13;&#10; point crossLPt(pVector _Off)&#13;&#10; {&#13;&#10; //注意先判断平行和重合&#13;&#10; point ret = s;&#13;&#10; double t = ((s.x - _Off.s.x) * (_Off.s.y - _Off.e.y) - (s.y - _Off.s.y) * (_Off.s.x - _Off.e.x))&#13;&#10; / ((s.x - e.x) * (_Off.s.y - _Off.e.y) - (s.y - e.y) * (_Off.s.x - _Off.e.x));&#13;&#10; ret.x &amp;#43;= (e.x - s.x) * t;&#13;&#10; ret.y &amp;#43;= (e.y - s.y) * t;&#13;&#10; return ret;&#13;&#10; }&#13;&#10;&#13;&#10; //------------线段和直线（向量）----------&#13;&#10; //线段和直线交&#13;&#10; //参数：线段[_Off]&#13;&#10; bool crossSL(const pVector &amp;amp;_Off) const&#13;&#10; {&#13;&#10; double rs = (*this) * _Off.s;&#13;&#10; double re = (*this) * _Off.e;&#13;&#10; return rs * re &amp;lt; eps;&#13;&#10; }&#13;&#10;&#13;&#10; //------------线段和线段（向量）----------&#13;&#10; //判断线段是否相交(注意添加eps)，参数：线段[_Off]&#13;&#10; bool isCrossSS(const pVector &amp;amp;_Off) const&#13;&#10; {&#13;&#10; //1.快速排斥试验判断以两条线段为对角线的两个矩形是否相交&#13;&#10; //2.跨立试验（等于0时端点重合）&#13;&#10; return (&#13;&#10; (std::max(s.x, e.x) &amp;gt;= std::min(_Off.s.x, _Off.e.x)) &amp;amp;&amp;amp;&#13;&#10; (std::max(_Off.s.x, _Off.e.x) &amp;gt;= std::min(s.x, e.x)) &amp;amp;&amp;amp;&#13;&#10; (std::max(s.y, e.y) &amp;gt;= std::min(_Off.s.y, _Off.e.y)) &amp;amp;&amp;amp;&#13;&#10; (std::max(_Off.s.y, _Off.e.y) &amp;gt;= std::min(s.y, e.y)) &amp;amp;&amp;amp;&#13;&#10; ((pVector(_Off.s, s) * _Off) * (_Off * pVector(_Off.s, e)) &amp;gt;= 0.0) &amp;amp;&amp;amp;&#13;&#10; ((pVector(s, _Off.s) * (*this)) * ((*this) * pVector(s, _Off.e)) &amp;gt;= 0.0)&#13;&#10; );&#13;&#10; }&#13;&#10;};&#13;&#10;&#13;&#10;class polygon&#13;&#10;{&#13;&#10;public:&#13;&#10; const static long maxpn = 100;&#13;&#10; point pt[maxpn];//点（顺时针或逆时针）&#13;&#10; long n;//点的个数&#13;&#10;&#13;&#10; point&amp;amp; operator[](int _p)&#13;&#10; {&#13;&#10; return pt[_p];&#13;&#10; }&#13;&#10;&#13;&#10; //求多边形面积，多边形内点必须顺时针或逆时针&#13;&#10; double area() const&#13;&#10; {&#13;&#10; double ans = 0.0;&#13;&#10; int i;&#13;&#10; for(i = 0; i &amp;lt; n; i &amp;#43;&amp;#43;)&#13;&#10; {&#13;&#10; int nt = (i &amp;#43; 1) % n;&#13;&#10; ans &amp;#43;= pt[i].x * pt[nt].y - pt[nt].x * pt[i].y;&#13;&#10; }&#13;&#10; return std::fabs(ans / 2.0);&#13;&#10; }&#13;&#10; //求多边形重心，多边形内点必须顺时针或逆时针&#13;&#10; point gravity() const&#13;&#10; {&#13;&#10; point ans;&#13;&#10; ans.x = ans.y = 0.0;&#13;&#10; int i;&#13;&#10; double area = 0.0;&#13;&#10; for(i = 0; i &amp;lt; n; i &amp;#43;&amp;#43;)&#13;&#10; {&#13;&#10; int nt = (i &amp;#43; 1) % n;&#13;&#10; double tp = pt[i].x * pt[nt].y - pt[nt].x * pt[i].y;&#13;&#10; area &amp;#43;= tp;&#13;&#10; ans.x &amp;#43;= tp * (pt[i].x &amp;#43; pt[nt].x);&#13;&#10; ans.y &amp;#43;= tp * (pt[i].y &amp;#43; pt[nt].y);&#13;&#10; }&#13;&#10; ans.x /= 3 * area;&#13;&#10; ans.y /= 3 * area;&#13;&#10; return ans;&#13;&#10; }&#13;&#10; //判断点在凸多边形内，参数：点[_Off]&#13;&#10; bool chas(const point &amp;amp;_Off) const&#13;&#10; {&#13;&#10; double tp = 0, np;&#13;&#10; int i;&#13;&#10; for(i = 0; i &amp;lt; n; i &amp;#43;&amp;#43;)&#13;&#10; {&#13;&#10; np = pVector(pt[i], pt[(i &amp;#43; 1) % n]) * _Off;&#13;&#10; if(tp * np &amp;lt; -eps)&#13;&#10; return false;&#13;&#10; tp = (std::fabs(np) &amp;gt; eps)?np: tp;&#13;&#10; }&#13;&#10; return true;&#13;&#10; }&#13;&#10; //判断点是否在任意多边形内[射线法]，O(n)&#13;&#10; bool ahas(const point &amp;amp;_Off) const&#13;&#10; {&#13;&#10; int ret = 0;&#13;&#10; double infv = 1e-10;//坐标系最大范围&#13;&#10; pVector l = pVector(_Off, point( -infv ,_Off.y));&#13;&#10; for(int i = 0; i &amp;lt; n; i &amp;#43;&amp;#43;)&#13;&#10; {&#13;&#10; pVector ln = pVector(pt[i], pt[(i &amp;#43; 1) % n]);&#13;&#10; if(fabs(ln.s.y - ln.e.y) &amp;gt; eps)&#13;&#10; {&#13;&#10; point tp = (ln.s.y &amp;gt; ln.e.y)? ln.s: ln.e;&#13;&#10; if(fabs(tp.y - _Off.y) &amp;lt; eps &amp;amp;&amp;amp; tp.x &amp;lt; _Off.x &amp;#43; eps)&#13;&#10; ret &amp;#43;&amp;#43;;&#13;&#10; }&#13;&#10; else if(ln.isCrossSS(l))&#13;&#10; ret &amp;#43;&amp;#43;;&#13;&#10; }&#13;&#10; return (ret % 2 == 1);&#13;&#10; }&#13;&#10; //凸多边形被直线分割,参数：直线[_Off]&#13;&#10; polygon split(pVector _Off)&#13;&#10; {&#13;&#10; //注意确保多边形能被分割&#13;&#10; polygon ret;&#13;&#10; point spt[2];&#13;&#10; double tp = 0.0, np;&#13;&#10; bool flag = true;&#13;&#10; int i, pn = 0, spn = 0;&#13;&#10; for(i = 0; i &amp;lt; n; i &amp;#43;&amp;#43;)&#13;&#10; {&#13;&#10; if(flag)&#13;&#10; pt[pn &amp;#43;&amp;#43;] = pt[i];&#13;&#10; else&#13;&#10; ret.pt[ret.n &amp;#43;&amp;#43;] = pt[i];&#13;&#10; np = _Off * pt[(i &amp;#43; 1) % n];&#13;&#10; if(tp * np &amp;lt; -eps)&#13;&#10; {&#13;&#10; flag = !flag;&#13;&#10; spt[spn &amp;#43;&amp;#43;] = _Off.crossLPt(pVector(pt[i], pt[(i &amp;#43; 1) % n]));&#13;&#10; }&#13;&#10; tp = (std::fabs(np) &amp;gt; eps)?np: tp;&#13;&#10; }&#13;&#10; ret.pt[ret.n &amp;#43;&amp;#43;] = spt[0];&#13;&#10; ret.pt[ret.n &amp;#43;&amp;#43;] = spt[1];&#13;&#10; n = pn;&#13;&#10; return ret;&#13;&#10; }&#13;&#10;&#13;&#10; //-------------凸包-------------&#13;&#10; //Graham扫描法，复杂度O(nlg(n)),结果为逆时针&#13;&#10; //#include &amp;lt;algorithm&amp;gt;&#13;&#10; static bool graham_cmp(const point &amp;amp;l, const point &amp;amp;r)//凸包排序函数&#13;&#10; {&#13;&#10; return l.y &amp;lt; r.y || (l.y == r.y &amp;amp;&amp;amp; l.x &amp;lt; r.x);&#13;&#10; }&#13;&#10; polygon&amp;amp; graham(point _p[], int _n)&#13;&#10; {&#13;&#10; int i, len;&#13;&#10; std::sort(_p, _p &amp;#43; _n, polygon::graham_cmp);&#13;&#10; n = 1;&#13;&#10; pt[0] = _p[0], pt[1] = _p[1];&#13;&#10; for(i = 2; i &amp;lt; _n; i &amp;#43;&amp;#43;)&#13;&#10; {&#13;&#10; while(n &amp;amp;&amp;amp; point::xmult(_p[i], pt[n], pt[n - 1]) &amp;gt;= 0)&#13;&#10; n --;&#13;&#10; pt[&amp;#43;&amp;#43; n] = _p[i];&#13;&#10; }&#13;&#10; len = n;&#13;&#10; pt[&amp;#43;&amp;#43; n] = _p[_n - 2];&#13;&#10; for(i = _n - 3; i &amp;gt;= 0; i --)&#13;&#10; {&#13;&#10; while(n != len &amp;amp;&amp;amp; point::xmult(_p[i], pt[n], pt[n - 1]) &amp;gt;= 0)&#13;&#10; n --;&#13;&#10; pt[&amp;#43;&amp;#43; n] = _p[i];&#13;&#10; }&#13;&#10; return (*this);&#13;&#10; }&#13;&#10;&#13;&#10; //凸包旋转卡壳(注意点必须顺时针或逆时针排列)&#13;&#10; //返回值凸包直径的平方（最远两点距离的平方）&#13;&#10; double rotating_calipers()&#13;&#10; {&#13;&#10; int i = 1;&#13;&#10; double ret = 0.0;&#13;&#10; pt[n] = pt[0];&#13;&#10; for(int j = 0; j &amp;lt; n; j &amp;#43;&amp;#43;)&#13;&#10; {&#13;&#10; while(fabs(point::xmult(pt[j], pt[j &amp;#43; 1], pt[i &amp;#43; 1])) &amp;gt; fabs(point::xmult(pt[j], pt[j &amp;#43; 1], pt[i])) &amp;#43; eps)&#13;&#10; i = (i &amp;#43; 1) % n;&#13;&#10; //pt[i]和pt[j],pt[i &amp;#43; 1]和pt[j &amp;#43; 1]可能是对踵点&#13;&#10; ret = std::max(ret, std::max(pt[i].dis(pt[j]), pt[i &amp;#43; 1].dis(pt[j &amp;#43; 1])));&#13;&#10; }&#13;&#10; return ret;&#13;&#10; }&#13;&#10;&#13;&#10; //凸包旋转卡壳(注意点必须逆时针排列)&#13;&#10; //返回值两凸包的最短距离&#13;&#10; double rotating_calipers(polygon &amp;amp;_Off)&#13;&#10; {&#13;&#10; int i = 0;&#13;&#10; double ret = 1e10;//inf&#13;&#10; pt[n] = pt[0];&#13;&#10; _Off.pt[_Off.n] = _Off.pt[0];&#13;&#10; //注意凸包必须逆时针排列且pt[0]是左下角点的位置&#13;&#10; while(_Off.pt[i &amp;#43; 1].y &amp;gt; _Off.pt[i].y)&#13;&#10; i = (i &amp;#43; 1) % _Off.n;&#13;&#10; for(int j = 0; j &amp;lt; n; j &amp;#43;&amp;#43;)&#13;&#10; {&#13;&#10; double tp;&#13;&#10; //逆时针时为 &amp;gt;,顺时针则相反&#13;&#10; while((tp = point::xmult(pt[j], pt[j &amp;#43; 1], _Off.pt[i &amp;#43; 1]) - point::xmult( pt[j], pt[j &amp;#43; 1], _Off.pt[i])) &amp;gt; eps)&#13;&#10; i = (i &amp;#43; 1) % _Off.n;&#13;&#10; //(pt[i],pt[i&amp;#43;1])和(_Off.pt[j],_Off.pt[j &amp;#43; 1])可能是最近线段&#13;&#10; ret = std::min(ret, pVector(pt[j], pt[j &amp;#43; 1]).dis(_Off.pt[i], true));&#13;&#10; ret = std::min(ret, pVector(_Off.pt[i], _Off.pt[i &amp;#43; 1]).dis(pt[j &amp;#43; 1], true));&#13;&#10; if(tp &amp;gt; -eps)//如果不考虑TLE问题最好不要加这个判断&#13;&#10; {&#13;&#10; ret = std::min(ret, pVector(pt[j], pt[j &amp;#43; 1]).dis(_Off.pt[i &amp;#43; 1], true));&#13;&#10; ret = std::min(ret, pVector(_Off.pt[i], _Off.pt[i &amp;#43; 1]).dis(pt[j], true));&#13;&#10; }&#13;&#10; }&#13;&#10; return ret;&#13;&#10; }&#13;&#10;&#13;&#10; //-----------半平面交-------------&#13;&#10; //复杂度:O(nlog2(n))&#13;&#10; //#include &amp;lt;algorithm&amp;gt;&#13;&#10; //半平面计算极角函数[如果考虑效率可以用成员变量记录]&#13;&#10; static double hpc_pa(const pVector &amp;amp;_Off)&#13;&#10; {&#13;&#10; return atan2(_Off.e.y - _Off.s.y, _Off.e.x - _Off.s.x);&#13;&#10; }&#13;&#10; //半平面交排序函数[优先顺序: 1.极角 2.前面的直线在后面的左边]&#13;&#10; static bool hpc_cmp(const pVector &amp;amp;l, const pVector &amp;amp;r)&#13;&#10; {&#13;&#10; double lp = hpc_pa(l), rp = hpc_pa(r);&#13;&#10; if(fabs(lp - rp) &amp;gt; eps)&#13;&#10; return lp &amp;lt; rp;&#13;&#10; return point::xmult(l.s, r.e, r.s) &amp;lt; 0.0;&#13;&#10; }&#13;&#10; //用于计算的双端队列&#13;&#10; pVector dequeue[maxpn];&#13;&#10; //获取半平面交的多边形（多边形的核）&#13;&#10; //参数：向量集合[l]，向量数量[ln];(半平面方向在向量左边）&#13;&#10; //函数运行后如果n[即返回多边形的点数量]为0则不存在半平面交的多边形（不存在区域或区域面积无穷大）&#13;&#10; polygon&amp;amp; halfPanelCross(pVector _Off[], int ln)&#13;&#10; {&#13;&#10; int i, tn;&#13;&#10; n = 0;&#13;&#10; std::sort(_Off, _Off &amp;#43; ln, hpc_cmp);&#13;&#10; //平面在向量左边的筛选&#13;&#10; for(i = tn = 1; i &amp;lt; ln; i &amp;#43;&amp;#43;)&#13;&#10; if(fabs(hpc_pa(_Off[i]) - hpc_pa(_Off[i - 1])) &amp;gt; eps)&#13;&#10; _Off[tn &amp;#43;&amp;#43;] = _Off[i];&#13;&#10; ln = tn;&#13;&#10; int bot = 0, top = 1;&#13;&#10; dequeue[0] = _Off[0];&#13;&#10; dequeue[1] = _Off[1];&#13;&#10; for(i = 2; i &amp;lt; ln; i &amp;#43;&amp;#43;)&#13;&#10; {&#13;&#10; if(dequeue[top].parallel(dequeue[top - 1]) ||&#13;&#10; dequeue[bot].parallel(dequeue[bot &amp;#43; 1]))&#13;&#10; return (*this);&#13;&#10; while(bot &amp;lt; top &amp;amp;&amp;amp;&#13;&#10; point::xmult(dequeue[top].crossLPt(dequeue[top - 1]), _Off[i].e, _Off[i].s) &amp;gt; eps)&#13;&#10; top --;&#13;&#10; while(bot &amp;lt; top &amp;amp;&amp;amp;&#13;&#10; point::xmult(dequeue[bot].crossLPt(dequeue[bot &amp;#43; 1]), _Off[i].e, _Off[i].s) &amp;gt; eps)&#13;&#10; bot &amp;#43;&amp;#43;;&#13;&#10; dequeue[&amp;#43;&amp;#43; top] = _Off[i];&#13;&#10; }&#13;&#10;&#13;&#10; while(bot &amp;lt; top &amp;amp;&amp;amp;&#13;&#10; point::xmult(dequeue[top].crossLPt(dequeue[top - 1]), dequeue[bot].e, dequeue[bot].s) &amp;gt; eps)&#13;&#10; top --;&#13;&#10; while(bot &amp;lt; top &amp;amp;&amp;amp;&#13;&#10; point::xmult(dequeue[bot].crossLPt(dequeue[bot &amp;#43; 1]), dequeue[top].e, dequeue[top].s) &amp;gt; eps)&#13;&#10; bot &amp;#43;&amp;#43;;&#13;&#10; //计算交点(注意不同直线形成的交点可能重合)&#13;&#10; if(top &amp;lt;= bot &amp;#43; 1)&#13;&#10; return (*this);&#13;&#10; for(i = bot; i &amp;lt; top; i &amp;#43;&amp;#43;)&#13;&#10; pt[n &amp;#43;&amp;#43;] = dequeue[i].crossLPt(dequeue[i &amp;#43; 1]);&#13;&#10; if(bot &amp;lt; top &amp;#43; 1)&#13;&#10; pt[n &amp;#43;&amp;#43;] = dequeue[bot].crossLPt(dequeue[top]);&#13;&#10; return (*this);&#13;&#10; }&#13;&#10;};&#13;&#10;class circle&#13;&#10;{&#13;&#10;public:&#13;&#10; point c;//圆心&#13;&#10; double r;//半径&#13;&#10; double db, de;//圆弧度数起点， 圆弧度数终点(逆时针0-360)&#13;&#10;&#13;&#10; //-------圆---------&#13;&#10;&#13;&#10; //判断圆在多边形内&#13;&#10; bool inside(const polygon &amp;amp;_Off) const&#13;&#10; {&#13;&#10; if(_Off.ahas(c) == false)&#13;&#10; return false;&#13;&#10; for(int i = 0; i &amp;lt; _Off.n; i &amp;#43;&amp;#43;)&#13;&#10; {&#13;&#10; pVector l = pVector(_Off.pt[i], _Off.pt[(i &amp;#43; 1) % _Off.n]);&#13;&#10; if(l.dis(c, true) &amp;lt; r - eps)&#13;&#10; return false;&#13;&#10; }&#13;&#10; return true;&#13;&#10; }&#13;&#10;&#13;&#10; //判断多边形在圆内（线段和折线类似）&#13;&#10; bool has(const polygon &amp;amp;_Off) const&#13;&#10; {&#13;&#10; for(int i = 0; i &amp;lt; _Off.n; i &amp;#43;&amp;#43;)&#13;&#10; if(_Off.pt[i].dis2(c) &amp;gt; r * r - eps)&#13;&#10; return false;&#13;&#10; return true;&#13;&#10; }&#13;&#10;&#13;&#10; //-------圆弧-------&#13;&#10; //圆被其他圆截得的圆弧，参数：圆[_Off]&#13;&#10; circle operator-(circle &amp;amp;_Off) const&#13;&#10; {&#13;&#10; //注意圆必须相交，圆心不能重合&#13;&#10; double d2 = c.dis2(_Off.c);&#13;&#10; double d = c.dis(_Off.c);&#13;&#10; double ans = std::acos((d2 &amp;#43; r * r - _Off.r * _Off.r) / (2 * d * r));&#13;&#10; point py = _Off.c - c;&#13;&#10; double oans = std::atan2(py.y, py.x);&#13;&#10; circle res;&#13;&#10; res.c = c;&#13;&#10; res.r = r;&#13;&#10; res.db = oans &amp;#43; ans;&#13;&#10; res.de = oans - ans &amp;#43; 2 * pi;&#13;&#10; return res;&#13;&#10; }&#13;&#10; //圆被其他圆截得的圆弧，参数：圆[_Off]&#13;&#10; circle operator&amp;#43;(circle &amp;amp;_Off) const&#13;&#10; {&#13;&#10; //注意圆必须相交，圆心不能重合&#13;&#10; double d2 = c.dis2(_Off.c);&#13;&#10; double d = c.dis(_Off.c);&#13;&#10; double ans = std::acos((d2 &amp;#43; r * r - _Off.r * _Off.r) / (2 * d * r));&#13;&#10; point py = _Off.c - c;&#13;&#10; double oans = std::atan2(py.y, py.x);&#13;&#10; circle res;&#13;&#10; res.c = c;&#13;&#10; res.r = r;&#13;&#10; res.db = oans - ans;&#13;&#10; res.de = oans &amp;#43; ans;&#13;&#10; return res;&#13;&#10; }&#13;&#10;&#13;&#10; //过圆外一点的两条切线&#13;&#10; //参数：点[_Off](必须在圆外),返回：两条切线(切线的s点为_Off,e点为切点)&#13;&#10; std::pair&amp;lt;pVector, pVector&amp;gt; tangent(const point &amp;amp;_Off) const&#13;&#10; {&#13;&#10; double d = c.dis(_Off);&#13;&#10; //计算角度偏移的方式&#13;&#10; double angp = std::acos(r / d), ango = std::atan2(_Off.y - c.y, _Off.x - c.x);&#13;&#10; point pl = point(c.x &amp;#43; r * std::cos(ango &amp;#43; angp), c.y &amp;#43; r * std::sin(ango &amp;#43; angp)),&#13;&#10; pr = point(c.x &amp;#43; r * std::cos(ango - angp), c.y &amp;#43; r * std::sin(ango - angp));&#13;&#10; return std::make_pair(pVector(_Off, pl), pVector(_Off, pr));&#13;&#10; }&#13;&#10;&#13;&#10; //计算直线和圆的两个交点&#13;&#10; //参数：直线[_Off](两点式)，返回两个交点，注意直线必须和圆有两个交点&#13;&#10; std::pair&amp;lt;point, point&amp;gt; cross(pVector _Off) const&#13;&#10; {&#13;&#10; _Off.pton();&#13;&#10; //到直线垂足的距离&#13;&#10; double td = fabs(_Off.a * c.x &amp;#43; _Off.b * c.y &amp;#43; _Off.c) / sqrt(_Off.a * _Off.a &amp;#43; _Off.b * _Off.b);&#13;&#10;&#13;&#10; //计算垂足坐标&#13;&#10; double xp = (_Off.b * _Off.b * c.x - _Off.a * _Off.b * c.y - _Off.a * _Off.c) / ( _Off.a * _Off.a &amp;#43; _Off.b * _Off.b);&#13;&#10; double yp = (- _Off.a * _Off.b * c.x &amp;#43; _Off.a * _Off.a * c.y - _Off.b * _Off.c) / (_Off.a * _Off.a &amp;#43; _Off.b * _Off.b);&#13;&#10;&#13;&#10; double ango = std::atan2(yp - c.y, xp - c.x);&#13;&#10; double angp = std::acos(td / r);&#13;&#10;&#13;&#10; return std::make_pair(point(c.x &amp;#43; r * std::cos(ango &amp;#43; angp), c.y &amp;#43; r * std::sin(ango &amp;#43; angp)),&#13;&#10; point(c.x &amp;#43; r * std::cos(ango - angp), c.y &amp;#43; r * std::sin(ango - angp)));&#13;&#10; }&#13;&#10;};&#13;&#10;&#13;&#10;class triangle&#13;&#10;{&#13;&#10;public:&#13;&#10; point a, b, c;//顶点&#13;&#10; triangle(){}&#13;&#10; triangle(point a, point b, point c): a(a), b(b), c(c){}&#13;&#10;&#13;&#10; //计算三角形面积&#13;&#10; double area()&#13;&#10; {&#13;&#10; return fabs(point::xmult(a, b, c)) / 2.0;&#13;&#10; }&#13;&#10;&#13;&#10; //计算三角形外心&#13;&#10; //返回：外接圆圆心&#13;&#10; point circumcenter()&#13;&#10; {&#13;&#10; pVector u,v;&#13;&#10; u.s.x = (a.x &amp;#43; b.x) / 2;&#13;&#10; u.s.y = (a.y &amp;#43; b.y) / 2;&#13;&#10; u.e.x = u.s.x - a.y &amp;#43; b.y;&#13;&#10; u.e.y = u.s.y &amp;#43; a.x - b.x;&#13;&#10; v.s.x = (a.x &amp;#43; c.x) / 2;&#13;&#10; v.s.y = (a.y &amp;#43; c.y) / 2;&#13;&#10; v.e.x = v.s.x - a.y &amp;#43; c.y;&#13;&#10; v.e.y = v.s.y &amp;#43; a.x - c.x;&#13;&#10; return u.crossLPt(v);&#13;&#10; }&#13;&#10;&#13;&#10; //计算三角形内心&#13;&#10; //返回：内接圆圆心&#13;&#10; point incenter()&#13;&#10; {&#13;&#10; pVector u, v;&#13;&#10; double m, n;&#13;&#10; u.s = a;&#13;&#10; m = atan2(b.y - a.y, b.x - a.x);&#13;&#10; n = atan2(c.y - a.y, c.x - a.x);&#13;&#10; u.e.x = u.s.x &amp;#43; cos((m &amp;#43; n) / 2);&#13;&#10; u.e.y = u.s.y &amp;#43; sin((m &amp;#43; n) / 2);&#13;&#10; v.s = b;&#13;&#10; m = atan2(a.y - b.y, a.x - b.x);&#13;&#10; n = atan2(c.y - b.y, c.x - b.x);&#13;&#10; v.e.x = v.s.x &amp;#43; cos((m &amp;#43; n) / 2);&#13;&#10; v.e.y = v.s.y &amp;#43; sin((m &amp;#43; n) / 2);&#13;&#10; return u.crossLPt(v);&#13;&#10; }&#13;&#10;&#13;&#10; //计算三角形垂心&#13;&#10; //返回：高的交点&#13;&#10; point perpencenter()&#13;&#10; {&#13;&#10; pVector u,v;&#13;&#10; u.s = c;&#13;&#10; u.e.x = u.s.x - a.y &amp;#43; b.y;&#13;&#10; u.e.y = u.s.y &amp;#43; a.x - b.x;&#13;&#10; v.s = b;&#13;&#10; v.e.x = v.s.x - a.y &amp;#43; c.y;&#13;&#10; v.e.y = v.s.y &amp;#43; a.x - c.x;&#13;&#10; return u.crossLPt(v);&#13;&#10; }&#13;&#10;&#13;&#10; //计算三角形重心&#13;&#10; //返回：重心&#13;&#10; //到三角形三顶点距离的平方和最小的点&#13;&#10; //三角形内到三边距离之积最大的点&#13;&#10; point barycenter()&#13;&#10; {&#13;&#10; pVector u,v;&#13;&#10; u.s.x = (a.x &amp;#43; b.x) / 2;&#13;&#10; u.s.y = (a.y &amp;#43; b.y) / 2;&#13;&#10; u.e = c;&#13;&#10; v.s.x = (a.x &amp;#43; c.x) / 2;&#13;&#10; v.s.y = (a.y &amp;#43; c.y) / 2;&#13;&#10; v.e = b;&#13;&#10; return u.crossLPt(v);&#13;&#10; }&#13;&#10;&#13;&#10; //计算三角形费马点&#13;&#10; //返回：到三角形三顶点距离之和最小的点&#13;&#10; point fermentpoint()&#13;&#10; {&#13;&#10; point u, v;&#13;&#10; double step = fabs(a.x) &amp;#43; fabs(a.y) &amp;#43; fabs(b.x) &amp;#43; fabs(b.y) &amp;#43; fabs(c.x) &amp;#43; fabs(c.y);&#13;&#10; int i, j, k;&#13;&#10; u.x = (a.x &amp;#43; b.x &amp;#43; c.x) / 3;&#13;&#10; u.y = (a.y &amp;#43; b.y &amp;#43; c.y) / 3;&#13;&#10; while (step &amp;gt; eps)&#13;&#10; {&#13;&#10; for (k = 0; k &amp;lt; 10; step /= 2, k &amp;#43;&amp;#43;)&#13;&#10; {&#13;&#10; for (i = -1; i &amp;lt;= 1; i &amp;#43;&amp;#43;)&#13;&#10; {&#13;&#10; for (j =- 1; j &amp;lt;= 1; j &amp;#43;&amp;#43;)&#13;&#10; {&#13;&#10; v.x = u.x &amp;#43; step * i;&#13;&#10; v.y = u.y &amp;#43; step * j;&#13;&#10; if (u.dis(a) &amp;#43; u.dis(b) &amp;#43; u.dis(c) &amp;gt; v.dis(a) &amp;#43; v.dis(b) &amp;#43; v.dis(c))&#13;&#10; u = v;&#13;&#10; }&#13;&#10; }&#13;&#10; }&#13;&#10; }&#13;&#10; return u;&#13;&#10; }&#13;&#10;};&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>简易四则运算(ACM个人模板)</title><link>//owent.net/2010/17.html</link><pubDate>Tue, 10 Aug 2010 18:40:31 +0000</pubDate><guid>//owent.net/2010/17.html</guid><description>&lt;pre&gt;&lt;code class="language-cpp"&gt;/**&#13;&#10; * 简易四则运算（栈实现）&#13;&#10; * #include &amp;lt;stack&amp;gt;&#13;&#10; * #include &amp;lt;cstring&amp;gt;&#13;&#10; */&#13;&#10;std::stack&amp;lt;char&amp;gt; opr;&#13;&#10;std::stack&amp;lt;double&amp;gt; num;&#13;&#10;char oprPRI[256];&#13;&#10;//初始化调用&#13;&#10;void initCalc()&#13;&#10;{&#13;&#10; //优先级设置&#13;&#10; char oprMap[7][2] = { {&amp;#39;&amp;#43;&amp;#39;, 1}, {&amp;#39;-&amp;#39;, 1}, {&amp;#39;*&amp;#39;, 2}, {&amp;#39;/&amp;#39;, 2}, {&amp;#39;^&amp;#39;, 3}, {&amp;#39;(&amp;#39;, 100}, {&amp;#39;)&amp;#39;, 0} };&#13;&#10; for(int i = 0; i &amp;lt; 7; i &amp;#43;&amp;#43;)&#13;&#10; oprPRI[oprMap[i][0]] = oprMap[i][1];&#13;&#10;}&#13;&#10;bool checkNum(char c)&#13;&#10;{&#13;&#10; return c == &amp;#39;.&amp;#39; || (c &amp;gt;= &amp;#39;0&amp;#39; &amp;amp;&amp;amp; c &amp;lt;= &amp;#39;9&amp;#39;);&#13;&#10;}&#13;&#10;double calcOpr(double l, double r, char opr)&#13;&#10;{&#13;&#10; switch(opr)&#13;&#10; {&#13;&#10; case &amp;#39;&amp;#43;&amp;#39;: return l &amp;#43; r;&#13;&#10; case &amp;#39;-&amp;#39;: return l - r;&#13;&#10; case &amp;#39;*&amp;#39;: return l * r;&#13;&#10; case &amp;#39;/&amp;#39;: return l / r;&#13;&#10; case &amp;#39;^&amp;#39;: return ::pow(l, r);&#13;&#10; }&#13;&#10; return 0.0;&#13;&#10;}&#13;&#10;void calcStack()&#13;&#10;{&#13;&#10; double cl, cr;&#13;&#10; cr = num.top();&#13;&#10; num.pop();&#13;&#10; cl = num.top();&#13;&#10; num.pop();&#13;&#10; num.push(::calcOpr(cl, cr, opr.top()));&#13;&#10; opr.pop();&#13;&#10;}&#13;&#10;double calc(const char str[])&#13;&#10;{&#13;&#10; while(!opr.empty())&#13;&#10; opr.pop();&#13;&#10; while(!num.empty())&#13;&#10; num.pop();&#13;&#10; int i = 0, len = strlen(str);&#13;&#10; num.push(0.0);&#13;&#10; opr.push(&amp;#39;(&amp;#39;);&#13;&#10; while(i &amp;lt; len)&#13;&#10; {&#13;&#10; if(::checkNum(str[i]))&#13;&#10; {&#13;&#10; double l;&#13;&#10; ::sscanf(str &amp;#43; i, &amp;#34;%lf&amp;#34;, &amp;amp;l);&#13;&#10; while(::checkNum(str[i]))&#13;&#10; i &amp;#43;&amp;#43;;&#13;&#10; num.push(l);&#13;&#10; }&#13;&#10; else&#13;&#10; {&#13;&#10; char c = str[i &amp;#43;&amp;#43;];&#13;&#10; if(c == &amp;#39;)&amp;#39;)&#13;&#10; {&#13;&#10; while(opr.top() != &amp;#39;(&amp;#39;)&#13;&#10; calcStack();&#13;&#10; opr.pop();&#13;&#10; }&#13;&#10; else if(oprPRI[c] &amp;gt; oprPRI[opr.top()])&#13;&#10; opr.push(c);&#13;&#10; else&#13;&#10; {&#13;&#10; while(opr.top() != &amp;#39;(&amp;#39; &amp;amp;&amp;amp; oprPRI[c] &amp;lt;= oprPRI[opr.top()])&#13;&#10; calcStack();&#13;&#10; opr.push(c);&#13;&#10; }&#13;&#10; }&#13;&#10; }&#13;&#10; while(opr.size() &amp;gt; 1)&#13;&#10; calcStack();&#13;&#10; return num.top();&#13;&#10;}&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>数论模板（个人模板）</title><link>//owent.net/2010/18.html</link><pubDate>Mon, 09 Aug 2010 15:54:02 +0000</pubDate><guid>//owent.net/2010/18.html</guid><description>&lt;h2 id="基础函数"&gt;基础函数:&lt;/h2&gt;&#10;&lt;pre&gt;&lt;code class="language-cpp"&gt;// 最大公约数,欧几里得定理&#13;&#10;int gcd(int a, int b)&#13;&#10;{&#13;&#10; return b?gcd(b, a % b): a;&#13;&#10;}&#13;&#10;// 拓展欧几里得定理&#13;&#10;// 求解ax &amp;#43; by = gcd(a,b)&#13;&#10;int ext_gcd(int a, int b, int &amp;amp;x, int &amp;amp;y)&#13;&#10;{&#13;&#10; int tmp, ret;&#13;&#10; if(!b)&#13;&#10; {&#13;&#10; x = 1;&#13;&#10; y = 0;&#13;&#10; return a;&#13;&#10; }&#13;&#10; ret = ext_gcd(b, a % b, x, y);&#13;&#10; tmp = x;&#13;&#10; x = y;&#13;&#10; y = tmp - (a / b) * y;&#13;&#10; return ret;&#13;&#10;}&#13;&#10;//交换数值&#13;&#10;void swap(int &amp;amp;a, int &amp;amp;b)&#13;&#10;{&#13;&#10; a ^= b ^= a ^= b;&#13;&#10;}&#13;&#10;&#13;&#10;/**&#13;&#10; * a的b次方Mod c&#13;&#10; * 参数为整数&#13;&#10; * 使用时注意修改类型&#13;&#10; */&#13;&#10;int PowerMod(int a, int b, int c)&#13;&#10;{&#13;&#10; int tp = 1;&#13;&#10; while (b)&#13;&#10; {&#13;&#10; if (b &amp;amp; 1)&#13;&#10; tp = (tp * a) % c;&#13;&#10; a = (a * a) % c;&#13;&#10; b &amp;gt;&amp;gt;= 1;&#13;&#10; }&#13;&#10; return tp;&#13;&#10;}&lt;/code&gt;&lt;/pre&gt;&#13;&#10;&lt;h2 id="1欧拉函数"&gt;1.欧拉函数&lt;/h2&gt;&#10;&lt;p&gt;Ψ（n） = 小于n且与n互质的数的个数&lt;/p&gt;</description></item><item><title>树状数组模块(个人模板)</title><link>//owent.net/2010/30.html</link><pubDate>Thu, 06 May 2010 13:51:29 +0000</pubDate><guid>//owent.net/2010/30.html</guid><description>&lt;p&gt;树状数组模块&lt;/p&gt;&#10;&lt;p&gt;ACM个人模板&lt;/p&gt;&#10;&lt;p&gt;POJ 2155 题目测试通过&lt;/p&gt;&#10;&lt;pre&gt;&lt;code class="language-cpp"&gt;/**&#13;&#10; * 树状数组模块&#13;&#10; * 下标从0开始&#13;&#10; */&#13;&#10;typedef long DG_Ran;&#13;&#10;typedef long DG_Num;&#13;&#10;const DG_Num DG_MAXN = 1005;&#13;&#10;&#13;&#10;//2^n&#13;&#10;DG_Num LowBit(DG_Num n)&#13;&#10;{&#13;&#10; return n &amp;amp; (-n);&#13;&#10;}&#13;&#10;//获取父节点索引&#13;&#10;DG_Num DGFather(DG_Num n)&#13;&#10;{&#13;&#10; return n &amp;#43; LowBit(n &amp;#43; 1);&#13;&#10;}&#13;&#10;//获取小的兄弟节点索引&#13;&#10;DG_Num DGBrother(DG_Num n)&#13;&#10;{&#13;&#10; return n - LowBit(n &amp;#43; 1);&#13;&#10;}&#13;&#10;//查找增加树状数组前pos项和&#13;&#10;//参数(树状数组[in],索引[in],初始赋0即查找前n项和[out])&#13;&#10;//复杂度:log(n)&#13;&#10;void DGFind(DG_Ran *g,DG_Num pos,DG_Ran &amp;amp;sum)&#13;&#10;{&#13;&#10; sum &amp;#43;= *(g &amp;#43; pos);&#13;&#10; if(pos &amp;gt;= LowBit(pos &amp;#43; 1))&#13;&#10; DGFind(g, pos - LowBit(pos &amp;#43; 1), sum);&#13;&#10;}&#13;&#10;//查找对应线性数组元素&#13;&#10;//参数(树状数组[in],索引[in]).&#13;&#10;//返回值:对应线性数组元素log(n)&#13;&#10;//复杂度:log(n)&#13;&#10;DG_Ran DGFindEle(DG_Ran *g,DG_Num pos)&#13;&#10;{&#13;&#10; DG_Ran a = 0 , b = 0;&#13;&#10; DGFind(g, pos, a);&#13;&#10; if(pos)&#13;&#10; {&#13;&#10; DGFind(g,pos - 1,b);&#13;&#10; return a - b;&#13;&#10; }&#13;&#10; else&#13;&#10; return a;&#13;&#10;}&#13;&#10;//树状数组,增加节点&#13;&#10;//参数:树状数组[out],原数组大小[in],新增线性数组值[in]&#13;&#10;//复杂度:log(n)&#13;&#10;DG_Ran DGAdd(DG_Ran *g,DG_Num n,DG_Ran val)&#13;&#10;{&#13;&#10; *(g &amp;#43; n) = val;&#13;&#10; DG_Num a = n;&#13;&#10; DG_Num b = 1;&#13;&#10; while((a &amp;amp; (~b)) != a)&#13;&#10; {&#13;&#10; *(g &amp;#43; n) &amp;#43;= *(g &amp;#43; a - 1);&#13;&#10; a &amp;amp;= (~b);&#13;&#10; b &amp;lt;&amp;lt;= 1;&#13;&#10; }&#13;&#10; return n &amp;#43; 1;&#13;&#10;}&#13;&#10;//构建树状数组&#13;&#10;//参数:线性数组[in],数组大小[in],树状数组[out]&#13;&#10;//复杂度:nlog(n)&#13;&#10;DG_Ran DGCreate(DG_Ran *g,DG_Num n,DG_Ran *tg)&#13;&#10;{&#13;&#10; DG_Num i;&#13;&#10; *tg = *g;&#13;&#10; for(i = 1 ; i &amp;lt; n ; i &amp;#43;&amp;#43;)&#13;&#10; DGAdd(tg,i,*(g &amp;#43; i));&#13;&#10; return n;&#13;&#10;}&#13;&#10;//修改指定位置值&#13;&#10;//参数:线性数组[in],数组位置[in],数组大小[in],新值[in]&#13;&#10;//复杂度:log(n)&#13;&#10;DG_Ran DGEdit(DG_Ran *g,DG_Num pos,DG_Num n,DG_Ran val)&#13;&#10;{&#13;&#10; DG_Num f = DGFather(pos);&#13;&#10; DG_Ran o = *( g &amp;#43; pos );&#13;&#10; *( g &amp;#43; pos ) = val;&#13;&#10; if(f &amp;lt; n)&#13;&#10; {&#13;&#10; DG_Ran fv = val - o &amp;#43; *( g &amp;#43; f );&#13;&#10; DGEdit(g, f, n, fv);&#13;&#10; }&#13;&#10; return n;&#13;&#10;}&#13;&#10;&#13;&#10;//树状数组的翻转(树状数组的应用)&#13;&#10;//一维 复杂度log(n)&#13;&#10;//小于等于指定位置的元素的翻转&amp;lt;=pos&#13;&#10;void DGDown1(DG_Ran g[],DG_Num pos,DG_Ran av)&#13;&#10;{&#13;&#10; while(pos &amp;gt;= 0)&#13;&#10; g[pos] &amp;#43;= av , pos = DGBrother(pos);&#13;&#10;}&#13;&#10;//获取位置pos的元素翻转次数&#13;&#10;DG_Ran DGCUp1(DG_Ran g[],DG_Num pos , DG_Num n)&#13;&#10;{&#13;&#10; DG_Ran t = 0;&#13;&#10; while(pos &amp;lt; n)&#13;&#10; t &amp;#43;= g[pos] , pos = DGFather(pos);&#13;&#10; return t;&#13;&#10;}&#13;&#10;//二维 复杂度(log(n))^2&#13;&#10;//小于等于指定位置的元素的翻转(0,0)-&amp;gt;(x,y)&#13;&#10;void DGDown2(DG_Ran g[][DG_MAXN],DG_Num x ,DG_Num y,DG_Ran av)&#13;&#10;{&#13;&#10; while(x &amp;gt;= 0)&#13;&#10; {&#13;&#10; DG_Num tmp = y;&#13;&#10; while (tmp &amp;gt;= 0)&#13;&#10; {&#13;&#10; g[x][tmp] &amp;#43;= av;&#13;&#10; tmp = DGBrother(tmp);&#13;&#10; }&#13;&#10; x = DGBrother(x);&#13;&#10; }&#13;&#10;}&#13;&#10;//获取位置(x,y)的元素翻转次数&#13;&#10;DG_Ran DGCUp2(DG_Ran g[][DG_MAXN],DG_Num x ,DG_Num y , DG_Num n)&#13;&#10;{&#13;&#10; DG_Ran t = 0;&#13;&#10; while(x &amp;lt; n)&#13;&#10; {&#13;&#10; DG_Num tmp = y;&#13;&#10; while (tmp &amp;lt; n)&#13;&#10; {&#13;&#10; t &amp;#43;= g[x][tmp];&#13;&#10; tmp = DGFather(tmp);&#13;&#10; }&#13;&#10; x = DGFather(x);&#13;&#10; }&#13;&#10; return t;&#13;&#10;}&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>线性筛法求质数(素数)表 及其原理</title><link>//owent.net/2010/32.html</link><pubDate>Mon, 03 May 2010 11:20:33 +0000</pubDate><guid>//owent.net/2010/32.html</guid><description>&lt;pre&gt;&lt;code class="language-cpp"&gt;/**&#13;&#10; * 线性筛法求素数表&#13;&#10; * 复杂度: O(n)&#13;&#10; */&#13;&#10;const long MAXP = 1000000;&#13;&#10;long prime[MAXP] = {0},num_prime = 0;&#13;&#10;int isNotPrime[MAXP] = {1, 1};&#13;&#10;void GetPrime_Init()//初始化调用&#13;&#10;{&#13;&#10; for(long i = 2 ; i &amp;lt; MAXP ; i &amp;#43;&amp;#43;)&#13;&#10; {&#13;&#10; if(! isNotPrime[i])&#13;&#10; prime[num_prime &amp;#43;&amp;#43;]=i;&#13;&#10; for(long j = 0 ; j &amp;lt; num_prime &amp;amp;&amp;amp; i * prime[j] &amp;lt; MAXP ; j &amp;#43;&amp;#43;)&#13;&#10; {&#13;&#10; isNotPrime[i * prime[j]] = 1;&#13;&#10; if( !(i % prime[j]))&#13;&#10; break;&#13;&#10; }&#13;&#10; }&#13;&#10;}&lt;/code&gt;&lt;/pre&gt;&#13;&#10;&lt;p&gt;线性筛法,即是筛选掉所有合数,留下质数&lt;/p&gt;</description></item><item><title>Hash模板 个人模板</title><link>//owent.net/2010/54.html</link><pubDate>Mon, 15 Mar 2010 12:58:47 +0000</pubDate><guid>//owent.net/2010/54.html</guid><description>&lt;pre&gt;&lt;code class="language-cpp"&gt;/**&#13;&#10; * Hash模板&#13;&#10; * Based: 0&#13;&#10; * template&amp;lt;unsigned long _SZ,class _T, unsigned long *pFun(_T _Off)&amp;gt;&#13;&#10; * class _My_Hash_ToInt&#13;&#10; * 传入数据大小_SZ,传入类型_T,Hash函数&#13;&#10; * 传入类型_T必须重载 = 和 == 符号&#13;&#10; * 收录了ELFHash函数&#13;&#10; * 主要是为了判重的简化些的模板&#13;&#10; * Hash算法性能比较见 http://www.cnblogs.com/lonelycatcher/archive/2011/08/23/2150587.html&#13;&#10; */&#13;&#10;&#13;&#10;const long hashsize = 51071; //Hash表大小(注意修改)&#13;&#10;// 各种Hash算法&#13;&#10;unsigned int SDBMHash(char *str)&#13;&#10;{&#13;&#10; unsigned int hash = hashsize;&#13;&#10;&#13;&#10; while (*str)&#13;&#10; {&#13;&#10; // equivalent to: hash = 65599*hash &amp;#43; (*str&amp;#43;&amp;#43;);&#13;&#10; hash = (*str&amp;#43;&amp;#43;) &amp;#43; (hash &amp;lt;&amp;lt; 6) &amp;#43; (hash &amp;lt;&amp;lt; 16) - hash;&#13;&#10; }&#13;&#10;&#13;&#10; return (hash &amp;amp; 0x7FFFFFFF);&#13;&#10;}&#13;&#10;&#13;&#10;// RS Hash Function&#13;&#10;unsigned int RSHash(char *str)&#13;&#10;{&#13;&#10; unsigned int b = 378551;&#13;&#10; unsigned int a = 63689;&#13;&#10; unsigned int hash = hashsize;&#13;&#10;&#13;&#10; while (*str)&#13;&#10; {&#13;&#10; hash = hash * a &amp;#43; (*str&amp;#43;&amp;#43;);&#13;&#10; a *= b;&#13;&#10; }&#13;&#10;&#13;&#10; return (hash &amp;amp; 0x7FFFFFFF);&#13;&#10;}&#13;&#10;&#13;&#10;// JS Hash Function&#13;&#10;unsigned int JSHash(char *str)&#13;&#10;{&#13;&#10; unsigned int hash = 1315423911;&#13;&#10;&#13;&#10; while (*str)&#13;&#10; {&#13;&#10; hash ^= ((hash &amp;lt;&amp;lt; 5) &amp;#43; (*str&amp;#43;&amp;#43;) &amp;#43; (hash &amp;gt;&amp;gt; 2));&#13;&#10; }&#13;&#10;&#13;&#10; return (hash &amp;amp; 0x7FFFFFFF);&#13;&#10;}&#13;&#10;&#13;&#10;// P. J. Weinberger Hash Function&#13;&#10;unsigned int PJWHash(char *str)&#13;&#10;{&#13;&#10; unsigned int BitsInUnignedInt = (unsigned int)(sizeof(unsigned int) * 8);&#13;&#10; unsigned int ThreeQuarters = (unsigned int)((BitsInUnignedInt * 3) / 4);&#13;&#10; unsigned int OneEighth = (unsigned int)(BitsInUnignedInt / 8);&#13;&#10; unsigned int HighBits = (unsigned int)(0xFFFFFFFF) &amp;lt;&amp;lt; (BitsInUnignedInt - OneEighth);&#13;&#10; unsigned int hash = hashsize;&#13;&#10; unsigned int test = 0;&#13;&#10;&#13;&#10; while (*str)&#13;&#10; {&#13;&#10; hash = (hash &amp;lt;&amp;lt; OneEighth) &amp;#43; (*str&amp;#43;&amp;#43;);&#13;&#10; if ((test = hash &amp;amp; HighBits) != 0)&#13;&#10; {&#13;&#10; hash = ((hash ^ (test &amp;gt;&amp;gt; ThreeQuarters)) &amp;amp; (~HighBits));&#13;&#10; }&#13;&#10; }&#13;&#10;&#13;&#10; return (hash &amp;amp; 0x7FFFFFFF);&#13;&#10;}&#13;&#10;&#13;&#10;// ELF Hash Function&#13;&#10;unsigned int ELFHash(char *str)&#13;&#10;{&#13;&#10; unsigned int hash = hashsize;&#13;&#10; unsigned int x = 0;&#13;&#10;&#13;&#10; while (*str)&#13;&#10; {&#13;&#10; hash = (hash &amp;lt;&amp;lt; 4) &amp;#43; (*str&amp;#43;&amp;#43;);&#13;&#10; if ((x = hash &amp;amp; 0xF0000000L) != 0)&#13;&#10; {&#13;&#10; hash ^= (x &amp;gt;&amp;gt; 24);&#13;&#10; hash &amp;amp;= ~x;&#13;&#10; }&#13;&#10; }&#13;&#10;&#13;&#10; return (hash &amp;amp; 0x7FFFFFFF);&#13;&#10;}&#13;&#10;&#13;&#10;// BKDR Hash Function&#13;&#10;unsigned int BKDRHash(char *str)&#13;&#10;{&#13;&#10; unsigned int seed = 131; // 31 131 1313 13131 131313 etc..&#13;&#10; unsigned int hash = hashsize;&#13;&#10;&#13;&#10; while (*str)&#13;&#10; {&#13;&#10; hash = hash * seed &amp;#43; (*str&amp;#43;&amp;#43;);&#13;&#10; }&#13;&#10;&#13;&#10; return (hash &amp;amp; 0x7FFFFFFF);&#13;&#10;}&#13;&#10;&#13;&#10;// DJB Hash Function&#13;&#10;unsigned int DJBHash(char *str)&#13;&#10;{&#13;&#10; unsigned int hash = 5381;&#13;&#10;&#13;&#10; while (*str)&#13;&#10; {&#13;&#10; hash &amp;#43;= (hash &amp;lt;&amp;lt; 5) &amp;#43; (*str&amp;#43;&amp;#43;);&#13;&#10; }&#13;&#10;&#13;&#10; return (hash &amp;amp; 0x7FFFFFFF);&#13;&#10;}&#13;&#10;&#13;&#10;// AP Hash Function&#13;&#10;unsigned int APHash(char *str)&#13;&#10;{&#13;&#10; unsigned int hash = hashsize;&#13;&#10; int i;&#13;&#10;&#13;&#10; for (i=0; *str; i&amp;#43;&amp;#43;)&#13;&#10; {&#13;&#10; if ((i &amp;amp; 1) == 0)&#13;&#10; {&#13;&#10; hash ^= ((hash &amp;lt;&amp;lt; 7) ^ (*str&amp;#43;&amp;#43;) ^ (hash &amp;gt;&amp;gt; 3));&#13;&#10; }&#13;&#10; else&#13;&#10; {&#13;&#10; hash ^= (~((hash &amp;lt;&amp;lt; 11) ^ (*str&amp;#43;&amp;#43;) ^ (hash &amp;gt;&amp;gt; 5)));&#13;&#10; }&#13;&#10; }&#13;&#10;&#13;&#10; return (hash &amp;amp; 0x7FFFFFFF);&#13;&#10;}&#13;&#10;&#13;&#10;// 程序模板&#13;&#10;template&amp;lt;typename _T&amp;gt;&#13;&#10;class _My_Hash_ToInt_Data&#13;&#10;{&#13;&#10;public:&#13;&#10; _My_Hash_ToInt_Data()&#13;&#10; {&#13;&#10; times = 0;&#13;&#10; next = -1;&#13;&#10; }&#13;&#10; _T data;&#13;&#10; long times;&#13;&#10; long next;&#13;&#10;};&#13;&#10;template&amp;lt;long _SZ,class _T, unsigned long pFun(_T&amp;amp; _Off)&amp;gt;&#13;&#10;class _My_Hash_ToInt&#13;&#10;{&#13;&#10;public:&#13;&#10; _My_Hash_ToInt()&#13;&#10; {&#13;&#10; memset(hash, -1, sizeof(hash));&#13;&#10; length = 0;&#13;&#10; };&#13;&#10; ~_My_Hash_ToInt(){};&#13;&#10; long find(_T _Off)&#13;&#10; {&#13;&#10; long pos = hash[pFun(_Off)];&#13;&#10; while(pos &amp;gt;= 0)&#13;&#10; {&#13;&#10; if(data[pos].data == _Off)&#13;&#10; return pos;&#13;&#10; else&#13;&#10; pos = data[pos].next;&#13;&#10; }&#13;&#10; return -1;&#13;&#10; }&#13;&#10; long insert(_T _Off)&#13;&#10; {&#13;&#10; long oldPos = pFun(_Off);&#13;&#10; long pos = hash[oldPos];&#13;&#10; while(pos &amp;gt;= 0)&#13;&#10; {&#13;&#10; if(data[pos].data == _Off)&#13;&#10; {&#13;&#10; data[pos].times &amp;#43;&amp;#43;;&#13;&#10; return pos;&#13;&#10; }&#13;&#10; else&#13;&#10; pos = data[pos].next;&#13;&#10; }&#13;&#10; data[length].data = _Off;&#13;&#10; data[length].times = 1;&#13;&#10; data[length].next = hash[oldPos];&#13;&#10; hash[oldPos] = length ;&#13;&#10; return length &amp;#43;&amp;#43;;&#13;&#10; }&#13;&#10; void clear()&#13;&#10; {&#13;&#10; length = 0;&#13;&#10; memset(hash, -1, sizeof(hash));&#13;&#10; memset(data, -1, sizeof(data));&#13;&#10; }&#13;&#10; //Member&#13;&#10; long length;&#13;&#10; _My_Hash_ToInt_Data&amp;lt;_T&amp;gt; data[_SZ];&#13;&#10; long hash[hashsize];&#13;&#10;};&#13;&#10;&#13;&#10;//节点类（注意修改）&#13;&#10;class node&#13;&#10;{&#13;&#10;public:&#13;&#10; char str[60];&#13;&#10; bool operator == (node &amp;amp;strin)&#13;&#10; {&#13;&#10; return !strcmp(str, strin.str);&#13;&#10; }&#13;&#10; node&amp;amp; operator = (node &amp;amp;strin)&#13;&#10; {&#13;&#10; strcpy(str, strin.str);&#13;&#10; return (*this);&#13;&#10; }&#13;&#10;};&#13;&#10;//扩展Hash函数（注意修改）&#13;&#10;unsigned long ELFHashEx(node &amp;amp;strIn)&#13;&#10;{&#13;&#10; return ELFHash(strIn.str);&#13;&#10;}&#13;&#10;_My_Hash_ToInt&amp;lt;10005, node, ELFHashEx&amp;gt;hash;//Hash类例子&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>最长单调子序列 复杂度nlog(n)</title><link>//owent.net/2009/74.html</link><pubDate>Wed, 16 Sep 2009 04:44:59 +0000</pubDate><guid>//owent.net/2009/74.html</guid><description>&lt;pre&gt;&lt;code class="language-cpp"&gt;//最长单调子序列 复杂度nlog(n)&#13;&#10;//参数(原序列,序列长度,生成的序列),传入序列长度必须大于0&#13;&#10;//返回值中lengthRecord中前k项表示长度为k的最小字序列&#13;&#10;//LIScmp为关系函数,原函数表明lengthRecord为递增(不含等于)&#13;&#10;typedef double LISTYPE;&#13;&#10;#define LISMAXN 10000&#13;&#10;int LIScmp(LISTYPE a,LISTYPE b)&#13;&#10;{&#13;&#10; return a &amp;lt; b;&#13;&#10;}&#13;&#10;long LISLength(LISTYPE list[],long n,LISTYPE lengthRecord[])&#13;&#10;{&#13;&#10; long length = 1,lth;&#13;&#10; LISTYPE lR[LISMAXN];&#13;&#10; lR[0] = list[0];&#13;&#10;&#13;&#10; for(int i = 1 ; i &amp;lt; n ; i &amp;#43;&amp;#43;)&#13;&#10; {&#13;&#10; //二分查找,复杂度 log(n)&#13;&#10; int b,e,m;&#13;&#10; b = 0;&#13;&#10; e = length - 1;&#13;&#10; while(b &amp;lt;= e &amp;amp;&amp;amp; e &amp;gt;= 0)&#13;&#10; {&#13;&#10; m = (b &amp;#43; e) / 2;&#13;&#10; if(LIScmp(lR[m],list[i]))&#13;&#10; b = m &amp;#43; 1;&#13;&#10; else&#13;&#10; e = m - 1;&#13;&#10; }&#13;&#10; lR[b] = list[i];&#13;&#10; if(b &amp;gt;= length)&#13;&#10; length &amp;#43;&amp;#43;;&#13;&#10; }&#13;&#10; /*&#13;&#10; *计算序列部分&#13;&#10; *复杂度nlog(n)&#13;&#10; */&#13;&#10; lth = 1;&#13;&#10; for(int i = 1 ; i &amp;lt; n ; i &amp;#43;&amp;#43;)&#13;&#10; {&#13;&#10; //二分查找,复杂度 log(n)&#13;&#10; int b,e,m;&#13;&#10; b = 0;&#13;&#10; e = lth - 1;&#13;&#10; while(b &amp;lt;= e &amp;amp;&amp;amp; e &amp;gt;= 0)&#13;&#10; {&#13;&#10; m = (b &amp;#43; e) / 2;&#13;&#10; if(LIScmp(lR[m],list[i]))&#13;&#10; b = m &amp;#43; 1;&#13;&#10; else&#13;&#10; e = m - 1;&#13;&#10; }&#13;&#10; lR[b] = list[i];&#13;&#10; if(b &amp;gt;= lth)&#13;&#10; lth &amp;#43;&amp;#43;;&#13;&#10; if(lth == length)&#13;&#10; {&#13;&#10; for(b = 0 ; b &amp;lt; length ; b &amp;#43;&amp;#43;)&#13;&#10; lengthRecord[b] = lR[b];&#13;&#10; break;&#13;&#10; }&#13;&#10; }&#13;&#10; //计算序列部分代码与之前的类似,可以直接Copy然后修改&#13;&#10; return length;&#13;&#10;}&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Prime最小生成树(个人模板)</title><link>//owent.net/2009/75.html</link><pubDate>Tue, 15 Sep 2009 16:43:29 +0000</pubDate><guid>//owent.net/2009/75.html</guid><description>&lt;pre&gt;&lt;code class="language-cpp"&gt;//Prime连通路模块&#13;&#10;#define N 1000 //最大数据规模&#13;&#10;#define MAXNUM 3000000 //最大路径长度&#13;&#10;typedef double PrimeType;//路径类型&#13;&#10;&#13;&#10;PrimeType PrimeRecord[N];&#13;&#10;PrimeType dis[N][N];&#13;&#10;int isLined[N] = {1,0};&#13;&#10;&#13;&#10;PrimeType GetPrimeLength(const long n)&#13;&#10;{&#13;&#10; PrimeType tmpLen = MAXNUM;&#13;&#10; long tmpPos = 0,left = n - 1;&#13;&#10; PrimeType sumLen = 0;&#13;&#10;&#13;&#10; for(long i = 1 ; i &amp;lt; n ; i &amp;#43;&amp;#43;)&#13;&#10; PrimeRecord[i] = dis[0][i];&#13;&#10; while(left --)&#13;&#10; {&#13;&#10; tmpLen = MAXNUM;&#13;&#10; for(long i = 1 ; i &amp;lt; n ; i &amp;#43;&amp;#43;)&#13;&#10; if(!isLined[i] &amp;amp;&amp;amp; PrimeRecord[i] &amp;lt; tmpLen)&#13;&#10; tmpPos = i,tmpLen = PrimeRecord[i];&#13;&#10;&#13;&#10; sumLen &amp;#43;= tmpLen;&#13;&#10; isLined[tmpPos] &amp;#43;&amp;#43;;&#13;&#10; for(long i = 1 ; i &amp;lt; n ; i &amp;#43;&amp;#43;)&#13;&#10; if(dis[tmpPos][i] &amp;lt; PrimeRecord[i])&#13;&#10; PrimeRecord[i] = dis[tmpPos][i];&#13;&#10; }&#13;&#10;&#13;&#10; return sumLen;&#13;&#10;}&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>矩阵相关 (增强中)</title><link>//owent.net/2009/76.html</link><pubDate>Tue, 15 Sep 2009 16:39:11 +0000</pubDate><guid>//owent.net/2009/76.html</guid><description>&lt;pre&gt;&lt;code class="language-cpp"&gt;//MULDATATYPE为矩阵元素类型,MAXMAT为最大矩阵大小&#13;&#10;&#13;&#10;typedef long MULDATATYPE;&#13;&#10;#define MAXMAT 100&#13;&#10;#define inf 1000000000&#13;&#10;&#13;&#10;#define fabs(x) ((x)&amp;gt;0?(x):-(x))&#13;&#10;#define zero(x) (fabs(x)&amp;lt;1e-10)&#13;&#10;&#13;&#10;struct mat&#13;&#10;{&#13;&#10; long n,m;&#13;&#10; MULDATATYPE data[MAXMAT][MAXMAT];&#13;&#10; void operator =(const mat&amp;amp; a);&#13;&#10; mat operator &amp;#43;(const mat&amp;amp; a);&#13;&#10; mat operator -(const mat&amp;amp; a);&#13;&#10; //0-1邻接矩阵&#13;&#10; mat operator &amp;amp;(const mat&amp;amp; a);&#13;&#10; mat operator |(const mat&amp;amp; a);&#13;&#10;};&#13;&#10;&#13;&#10;//c=a*b&#13;&#10;//注意引用&#13;&#10;int Mat_MulMode(mat&amp;amp; c,const mat&amp;amp; a,const mat&amp;amp; b,MULDATATYPE mod)&#13;&#10;{&#13;&#10; long i,j,k;&#13;&#10; if (a.m != b.n)&#13;&#10; return 0;&#13;&#10; c.n = a.n , c.m = b.m;&#13;&#10; for (i = 0 ; i &amp;lt; c.n ; i &amp;#43;&amp;#43;)&#13;&#10; for (j = 0 ; j &amp;lt; c.m ; j &amp;#43;&amp;#43;)&#13;&#10; for (c.data[i][j] = k = 0 ; k &amp;lt; a.m ; k &amp;#43;&amp;#43;)&#13;&#10; c.data[i][j] = (c.data[i][j] &amp;#43; a.data[i][k] * b.data[k][j]) % mod;&#13;&#10; return 1;&#13;&#10;}&#13;&#10;//c=a^b(其中必须满足b&amp;gt;0)&#13;&#10;int Mat_PowMode(mat&amp;amp; c,mat a,long b,MULDATATYPE mod)&#13;&#10;{&#13;&#10; c = a;&#13;&#10; b --;&#13;&#10; while(b)&#13;&#10; {&#13;&#10; mat tmp;&#13;&#10; if(b &amp;amp; 1)&#13;&#10; {&#13;&#10; tmp = c;&#13;&#10; Mat_MulMode(c,tmp,a,mod);&#13;&#10; }&#13;&#10; tmp = a;&#13;&#10; Mat_MulMode(a,tmp,tmp,mod);&#13;&#10; b = b&amp;gt;&amp;gt;1;&#13;&#10; }&#13;&#10; return 1;&#13;&#10;}&#13;&#10;//c=a&amp;#43;b&#13;&#10;int Mat_AddMode(mat&amp;amp; c,const mat&amp;amp; a,const mat&amp;amp; b,MULDATATYPE mod)&#13;&#10;{&#13;&#10; long i,j;&#13;&#10; if (a.n != b.n || a.m != b.m)&#13;&#10; return 0;&#13;&#10; c.n = a.n , c.m = b.m;&#13;&#10; for (i = 0 ; i &amp;lt; c.n ; i &amp;#43;&amp;#43;)&#13;&#10; for (j = 0 ; j &amp;lt; c.m ; j &amp;#43;&amp;#43;)&#13;&#10; c.data[i][j] = (a.data[i][j] &amp;#43; b.data[i][j]) % mod;&#13;&#10; return 1;&#13;&#10;}&#13;&#10;//c=a-b&#13;&#10;int Mat_SubMode(mat&amp;amp; c,const mat&amp;amp; a,const mat&amp;amp; b,MULDATATYPE mod)&#13;&#10;{&#13;&#10; long i,j;&#13;&#10; if (a.n != b.n || a.m != b.m)&#13;&#10; return 0;&#13;&#10; c.n = a.n , c.m = b.m;&#13;&#10; for (i = 0 ; i &amp;lt; c.n ; i &amp;#43;&amp;#43;)&#13;&#10; for (j = 0 ; j &amp;lt; c.m ; j &amp;#43;&amp;#43;)&#13;&#10; c.data[i][j] = (a.data[i][j] - b.data[i][j]) % mod;&#13;&#10; return 1;&#13;&#10;}&#13;&#10;&#13;&#10;&#13;&#10;void mat::operator =(const mat&amp;amp; a)&#13;&#10;{&#13;&#10; n = a.n;&#13;&#10; m = a.m;&#13;&#10; for(int i = 0 ; i &amp;lt; n ; i &amp;#43;&amp;#43;)&#13;&#10; for(int j = 0 ; j &amp;lt; m ; j &amp;#43;&amp;#43;)&#13;&#10; data[i][j] = a.data[i][j];&#13;&#10;}&#13;&#10;mat mat::operator &amp;#43;(const mat &amp;amp;a)&#13;&#10;{&#13;&#10; long i,j;&#13;&#10; mat tmpMat;&#13;&#10; tmpMat.m = m;&#13;&#10; tmpMat.n = n;&#13;&#10; for(i = 0 ; i &amp;lt; n ; i &amp;#43;&amp;#43;)&#13;&#10; for(j = 0 ; j &amp;lt; m ; j &amp;#43;&amp;#43;)&#13;&#10; tmpMat.data[i][j] = data[i][j] &amp;#43; a.data[i][j];&#13;&#10; return tmpMat;&#13;&#10;}&#13;&#10;mat mat::operator -(const mat &amp;amp;a)&#13;&#10;{&#13;&#10; long i,j;&#13;&#10; mat tmpMat;&#13;&#10; tmpMat.m = m;&#13;&#10; tmpMat.n = n;&#13;&#10; for(i = 0 ; i &amp;lt; n ; i &amp;#43;&amp;#43;)&#13;&#10; for(j = 0 ; j &amp;lt; m ; j &amp;#43;&amp;#43;)&#13;&#10; tmpMat.data[i][j] = data[i][j] - a.data[i][j];&#13;&#10; return tmpMat;&#13;&#10;}&#13;&#10;mat mat::operator &amp;amp;(const mat &amp;amp;a)&#13;&#10;{&#13;&#10; long i,j;&#13;&#10; mat tmpMat;&#13;&#10; tmpMat.m = m;&#13;&#10; tmpMat.n = n;&#13;&#10; for(i = 0 ; i &amp;lt; n ; i &amp;#43;&amp;#43;)&#13;&#10; for(j = 0 ; j &amp;lt; m ; j &amp;#43;&amp;#43;)&#13;&#10; tmpMat.data[i][j] = data[i][j] &amp;amp; a.data[i][j];&#13;&#10; return tmpMat;&#13;&#10;}&#13;&#10;mat mat::operator |(const mat &amp;amp;a)&#13;&#10;{&#13;&#10; long i,j;&#13;&#10; mat tmpMat;&#13;&#10; tmpMat.m = m;&#13;&#10; tmpMat.n = n;&#13;&#10; for(i = 0 ; i &amp;lt; n ; i &amp;#43;&amp;#43;)&#13;&#10; for(j = 0 ; j &amp;lt; m ; j &amp;#43;&amp;#43;)&#13;&#10; tmpMat.data[i][j] = data[i][j] | a.data[i][j];&#13;&#10; return tmpMat;&#13;&#10;}&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>点到直线距离 和 线段间最短距离 (OWenT 模板)</title><link>//owent.net/2009/80.html</link><pubDate>Fri, 14 Aug 2009 11:33:38 +0000</pubDate><guid>//owent.net/2009/80.html</guid><description>&lt;p&gt;点到直线距离&lt;/p&gt;&#10;&lt;pre&gt;&lt;code class="language-cpp"&gt;// (x0,y0)到(x1,y1)和(x2,y2)确定的直线的距离&#13;&#10;&#13;&#10;double disBetweenPointAndLine(double x0,double y0,double x1,double y1,double x2,double y2)&#13;&#10;{&#13;&#10; //化为ax&amp;#43;by&amp;#43;c=0的形式&#13;&#10; double a = y1-y2;&#13;&#10; double b = x2-x1;&#13;&#10; double c = x1*y2-x2*y1;&#13;&#10; double d = (a*x0&amp;#43;b*y0&amp;#43;c)/sqrt(a*a&amp;#43;b*b);&#13;&#10; /*&#13;&#10; 如果是线段判断垂足&#13;&#10;&#13;&#10; double xp = (b*b*x0-a*b*y0-a*c)/(a*a&amp;#43;b*b);&#13;&#10; double yp = (-a*b*x0&amp;#43;a*a*y0-b*c)/(a*a&amp;#43;b*b);&#13;&#10; double xb = (x1&amp;gt;x2)?x1:x2;&#13;&#10; double yb = (y1&amp;gt;y2)?y1:y2;&#13;&#10; double xs = x1&amp;#43;x2-xb;&#13;&#10; double ys = y1&amp;#43;y2-yb;&#13;&#10; if(xp &amp;gt; xb || xp &amp;lt; xs || yp &amp;gt; yb || yp &amp;lt; ys)&#13;&#10; {&#13;&#10; d = sqrt((x0 - x1) * (x0 - x1) &amp;#43; (y0 - y1) * (y0 - y1));&#13;&#10; if(d &amp;gt; sqrt((x0 - x2) * (x0 - x2) &amp;#43; (y0 - y2) * (y0 - y2)))&#13;&#10; d = sqrt((x0 - x2) * (x0 - x2) &amp;#43; (y0 - y2) * (y0 - y2));&#13;&#10; }&#13;&#10; */&#13;&#10; return fabs(d);&#13;&#10;}&lt;/code&gt;&lt;/pre&gt;&#13;&#10;&lt;p&gt;线段间最短距离&lt;/p&gt;</description></item><item><title>连接最多点直线 (OWenT 个人模板)</title><link>//owent.net/2009/81.html</link><pubDate>Fri, 14 Aug 2009 11:30:49 +0000</pubDate><guid>//owent.net/2009/81.html</guid><description>&lt;pre&gt;&lt;code class="language-cpp"&gt;//n每个用例的点个数&#13;&#10;//MAXN为最大点个数&#13;&#10;//PTYPE为坐标值类型&#13;&#10;#include&amp;lt;iostream&amp;gt;&#13;&#10;#include&amp;lt;cmath&amp;gt;&#13;&#10;using namespace std;&#13;&#10;&#13;&#10;#define MAXN 1005&#13;&#10;#define EPS 1e-10&#13;&#10;typedef double PTYPE;&#13;&#10;&#13;&#10;struct point&#13;&#10;{&#13;&#10; PTYPE x,y;&#13;&#10;};&#13;&#10;struct node&#13;&#10;{&#13;&#10; PTYPE k;&#13;&#10;};&#13;&#10;int cmp(const void * a, const void * b)&#13;&#10;{&#13;&#10; return((*(PTYPE*)a-*(PTYPE*)b&amp;gt;0)?1:-1);&#13;&#10;}&#13;&#10;node numK[MAXN * MAXN / 2];&#13;&#10;point pt[MAXN];&#13;&#10;int main()&#13;&#10;{&#13;&#10;&#13;&#10; int n , maxNum = 1 , tmpNum = 0;&#13;&#10; while(scanf(&amp;#34;%d&amp;#34;,&amp;amp;n),n)&#13;&#10; {&#13;&#10; for(int i = 0 ; i &amp;lt; n ; i &amp;#43;&amp;#43;)&#13;&#10; scanf(&amp;#34;%lf %lf&amp;#34;,&amp;amp;pt[i].x,&amp;amp;pt[i].y);&#13;&#10; for(int i = 0 ; i &amp;lt; n ; i &amp;#43;&amp;#43;)&#13;&#10; {&#13;&#10; int pos = 0;&#13;&#10; for(int j = i &amp;#43; 1 ; j &amp;lt; n ; j &amp;#43;&amp;#43;)&#13;&#10; if((pt[i].x - pt[j].x) &amp;gt; EPS)&#13;&#10; numK[pos &amp;#43;&amp;#43;].k = (pt[j].y - pt[i].y) / (pt[j].x - pt[i].x);&#13;&#10; else&#13;&#10; numK[pos &amp;#43;&amp;#43;].k = 100000;&#13;&#10;&#13;&#10; qsort(numK,pos,sizeof(numK[0]),cmp);&#13;&#10; int tmpNum = 2;&#13;&#10; for(int j = 1 ; j &amp;lt; pos ; j &amp;#43;&amp;#43;)&#13;&#10; {&#13;&#10; if(numK[j].k == numK[j - 1].k)&#13;&#10; tmpNum &amp;#43;&amp;#43;;&#13;&#10; else&#13;&#10; {&#13;&#10; if(tmpNum &amp;gt; maxNum)&#13;&#10; maxNum = tmpNum;&#13;&#10; tmpNum = 2;&#13;&#10; }&#13;&#10; }&#13;&#10; if(tmpNum &amp;gt; maxNum)&#13;&#10; maxNum = tmpNum;&#13;&#10; }&#13;&#10;&#13;&#10;&#13;&#10; printf(&amp;#34;%d\n&amp;#34;,maxNum);&#13;&#10; maxNum = 1;&#13;&#10; }&#13;&#10; return 0;&#13;&#10;}&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>并查集 模板</title><link>//owent.net/2009/91.html</link><pubDate>Wed, 15 Jul 2009 09:05:54 +0000</pubDate><guid>//owent.net/2009/91.html</guid><description>&lt;pre&gt;&lt;code class="language-cpp"&gt;//并查集&#13;&#10;//注意类型匹配&#13;&#10;const int maxn = 100002;&#13;&#10;int DSet[maxn];&#13;&#10;void init(int n) {&#13;&#10; for(int i = 0 ; i &amp;lt;= n ; i &amp;#43;&amp;#43;)&#13;&#10; DSet[i] = i;&#13;&#10;}&#13;&#10;int findP(int id) {&#13;&#10;if(DSet[id] != id)&#13;&#10; DSet[id] = findP(DSet[id]);&#13;&#10; return DSet[id];&#13;&#10;}&#13;&#10;//返回根节点ID&#13;&#10;int UnionEle(int a,int b) {&#13;&#10; a = findP(a);&#13;&#10; b = findP(b);&#13;&#10; if(a &amp;gt; b)&#13;&#10; a ^= b ^= a ^= b;&#13;&#10; DSet[b] = a;&#13;&#10; return a;&#13;&#10;}&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>模式匹配(kmp)个人模板</title><link>//owent.net/2009/92.html</link><pubDate>Mon, 06 Jul 2009 20:34:01 +0000</pubDate><guid>//owent.net/2009/92.html</guid><description>&lt;pre&gt;&lt;code class="language-cpp"&gt;/**&#13;&#10; * KMP模式匹配&#13;&#10; * 算法复杂度O(m&amp;#43;n)&#13;&#10; * ACM 模板 &#13;&#10; *&#13;&#10; * @Author OWenT&#13;&#10; * @link http://www.owent.net&#13;&#10; */&#13;&#10;&#13;&#10;// 最大字符串长度&#13;&#10;const int maxLen = 10000;&#13;&#10;// 前一个匹配位置,多次匹配注意要重新初始化&#13;&#10;// 注：preMatch[i]表示0~preMatch[i-1]能和?~i匹配&#13;&#10;int preMatch[maxLen]={0};&#13;&#10;&#13;&#10;/**&#13;&#10; * kmp匹配算法&#13;&#10; * @param char[] source 查找源&#13;&#10; * @param char[] checked 查找目标&#13;&#10; * @return int 根据以下两个分支返回值分别表示不同的含义&#13;&#10; */&#13;&#10;int kmp_match(char source[],char checked[]) {&#13;&#10; int i = 0, j = 0;&#13;&#10; memset(preMatch, 0, sizeof(preMatch));&#13;&#10;&#13;&#10; if(!checked[i]) // 被匹配串为空串，直接返回 0&#13;&#10; return 0;&#13;&#10;&#13;&#10; &amp;#43;&amp;#43; i;&#13;&#10; while(checked[i]) {&#13;&#10; for(j = preMatch[i - 1]; checked[i] != checked[j] &amp;amp;&amp;amp; j; j = preMatch[j - 1]);&#13;&#10; preMatch[i] = (checked[i] == checked[j])? j &amp;#43; 1 : 0 ;&#13;&#10; &amp;#43;&amp;#43; i;&#13;&#10; }&#13;&#10; //计算匹配子串个数(子串间无重叠)(与以下一起二选一)&#13;&#10; int num = 0;//计数变量&#13;&#10; for(i = j = 0; source[i]; &amp;#43;&amp;#43; i) {&#13;&#10; if(checked[j] == source[i])&#13;&#10; &amp;#43;&amp;#43; j;&#13;&#10; else if(j)&#13;&#10; -- i, j = preMatch[j - 1];&#13;&#10;&#13;&#10; if(!checked[j])&#13;&#10; &amp;#43;&amp;#43; num, j = 0;//如果要子串间重叠 则此句中j = 0 改成 j = preMatch[j - 1]&#13;&#10; }&#13;&#10; return num;&#13;&#10;&#13;&#10; //计算首个匹配子串位置(与以上一起二选一)&#13;&#10; for(i = j = 0; checked[j] &amp;amp;&amp;amp; source[i]; &amp;#43;&amp;#43; i) {&#13;&#10; if(checked[j] == source[i])&#13;&#10; &amp;#43;&amp;#43; j;&#13;&#10; else if(j)&#13;&#10; -- i, j = preMatch[j - 1];&#13;&#10; }&#13;&#10;&#13;&#10; //返回匹配的串的第一个字符出现位置(从1开始计数,0表示无匹配)&#13;&#10; if(!checked[j])&#13;&#10; return i - j &amp;#43; 1;&#13;&#10; else&#13;&#10; return 0;&#13;&#10;&#13;&#10; return 0;&#13;&#10;}&lt;/code&gt;&lt;/pre&gt;</description></item></channel></rss>