模板(数据结构)

数据结构:

链式前向星(存储结构)

矩阵快速幂

树状数组

RMQ问题

线段树

manacher算法




链式前向星(存储结构)

http://blog.csdn.net/acdreamers/article/details/16902023  // 具体解析;

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. // 按边存储  
  2. struct Edge  
  3. {  
  4.      int next;  
  5.      int to;  
  6.      int w;  
  7. };  
  8.   
  9. void add(int u,int v,int w)  
  10. {  
  11.     edge[cnt].w = w;  
  12.     edge[cnt].to = v;  
  13.     edge[cnt].next = head[u];  
  14.     head[u] = cnt++;  
  15. }  


矩阵快速幂:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. struct mat{  
  2.     long long arr[2][2];  
  3.     mat(){ memset(arr, 0, sizeof(arr)); }  
  4.     mat mul(mat &b){  
  5.         mat res;  
  6.         for(int i = 0; i < 2; ++i){  
  7.             for(int k = 0; k < 2; ++k){  
  8.                 if(this->arr[i][k]){   //优化:0特别多时,复杂度可能会降低到O(n^2)  
  9.                     for(int j = 0; j < 2; ++j){  
  10.                         res.arr[i][j] += this->arr[i][k]*b.arr[k][j];  
  11.                         if(res.arr[i][j] >= MOD) res.arr[i][j]%=MOD;  
  12.                     }  
  13.                 }  
  14.             }  
  15.         }  
  16.         return res;  
  17.     }  
  18. };  



树状数组:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. // 注意树状数组下标从1开始;  
  2. inline int lowbit(int x){  
  3.     return x&-x;  
  4. }  
  5. int sum(int x){  
  6.     int ret = 0;  
  7.     while(x > 0) { ret += C[x]; x -= lowbit(x); }  
  8.     return ret;  
  9. }  
  10. void add(int x, int d){  // 点修改;  
  11.     while(x <= n){  
  12.         C[x] += d; x += lowbit(x);  
  13.     }  
  14. }  


RMQ问题:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. void RMQ_init(const vector<int> &A){    // d[i][j] 表示从i开始,长度为2^j的一段元素中的最小值;  
  2.     int n = A.size();  
  3.     for(int i = 0; i < n; ++i)  d[i][0] = A[i];  
  4.     for(int j = 1; (1<<j) <= n; ++j){  
  5.         for(int i = 0; i+(1<<j)-1 < n; ++i)  
  6.             d[i][j] = min(d[i][j-1], d[i+(1<<(j-1))][j-1]);  
  7.     }  
  8. }  
  9. int RMQ(int L, int R){  
  10.     int k = 0;  
  11.     while((1<<(k+1)) <= R-L+1) k++; // 如果2^(k+1) <= R-L+1, 那么k还可以加1;  
  12.     return min(d[L][k], d[R-(1<<k)+1][k]);  
  13. }  


线段树区间更新,区间覆盖;

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. int _sum, _min, _max, y1, y2;  //y1, y2表示查询的区间;  
  2.   
  3. struct IntervalTree {  
  4.   int sumv[maxnode], minv[maxnode], maxv[maxnode], setv[maxnode], addv[maxnode];  
  5.   
  6.   // 维护信息  
  7.   void maintain(int o, int L, int R) {  
  8.     int lc = o*2, rc = o*2+1;   // 这里注意的是,如果是点跟新需要加一句 sumv[o] = minv[o] = maxv[o] = 0;   
  9.     if(R > L) {  
  10.       sumv[o] = sumv[lc] + sumv[rc];  
  11.       minv[o] = min(minv[lc], minv[rc]);  
  12.       maxv[o] = max(maxv[lc], maxv[rc]);  
  13.     }  
  14.     if(setv[o] >= 0) { minv[o] = maxv[o] = setv[o]; sumv[o] = setv[o] * (R-L+1); }  
  15.     if(addv[o]) { minv[o] += addv[o]; maxv[o] += addv[o]; sumv[o] += addv[o] * (R-L+1); }  
  16.   }  
  17.   
  18.   // 标记传递  
  19.   void pushdown(int o) {  
  20.     int lc = o*2, rc = o*2+1;  
  21.     if(setv[o] >= 0) {  
  22.       setv[lc] = setv[rc] = setv[o];  
  23.       addv[lc] = addv[rc] = 0;  
  24.       setv[o] = -1; // 清除本结点标记  
  25.     }  
  26.     if(addv[o]) {  
  27.       addv[lc] += addv[o];  
  28.       addv[rc] += addv[o];  
  29.       addv[o] = 0; // 清除本结点标记  
  30.     }  
  31.   }  
  32.   
  33.   void update(int o, int L, int R) {  
  34.     int lc = o*2, rc = o*2+1;  
  35.     if(y1 <= L && y2 >= R) { // 标记修改        
  36.       if(op == 1) addv[o] += v;  //根据题目要求修改;  
  37.       else { setv[o] = v; addv[o] = 0; }  
  38.     } else {  
  39.       pushdown(o);  
  40.       int M = L + (R-L)/2;  
  41.       if(y1 <= M) update(lc, L, M); else maintain(lc, L, M);  
  42.       if(y2 > M) update(rc, M+1, R); else maintain(rc, M+1, R);  
  43.     }  
  44.     maintain(o, L, R);  
  45.   }  
  46.   
  47.   void query(int o, int L, int R, int add) {  
  48.     if(setv[o] >= 0) {  
  49.       int v = setv[o] + add + addv[o];  
  50.       _sum += v * (min(R,y2)-max(L,y1)+1);  
  51.       _min = min(_min, v);  
  52.       _max = max(_max, v);  
  53.     } else if(y1 <= L && y2 >= R) {  
  54.       _sum += sumv[o] + add * (R-L+1);  
  55.       _min = min(_min, minv[o] + add);  
  56.       _max = max(_max, maxv[o] + add);  
  57.     } else {  
  58.       int M = L + (R-L)/2;  
  59.       if(y1 <= M) query(o*2, L, M, add + addv[o]);  
  60.       if(y2 > M) query(o*2+1, M+1, R, add + addv[o]);  
  61.     }  
  62.   }  
  63. };  



kmp模板

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. /* 
  2.  * kmp算法 
  3.  * 时间复杂度O(n+m); 
  4.  */  
  5.   
  6.   
  7. // 获得Next数组;  
  8. void getNext(int len){  
  9.     int j, k;  
  10.     j = 0; k = -1; Next[0] = -1;  
  11.     while(j <= len){  
  12.         if(k == -1 || word[j] == word[k]){  
  13.             ++j; ++k;  
  14.             if(word[j] != word[k]) Next[j] = k;  
  15.             else Next[j] = Next[k];  
  16.         } else  
  17.             k = Next[k];  
  18.     }  
  19. }  
  20.   
  21.   
  22. //返回模式串在主串S中出现的次数  
  23. int kmpCount(){  
  24.     int ans = 0;  
  25.     int j = 0; // j表示匹配的模式串位置;  
  26.     int slen = strlen(test);  
  27.     int tlen = strlen(word);  
  28.     for(int i = 0; i < slen; ){  
  29.         if(j == -1 || word[j] == test[i]) i++, j++;  
  30.         else j = Next[j];  
  31.         if(j == tlen){  
  32.             ans++;  
  33.             j = Next[j];  
  34.         }  
  35.     }  
  36.     return ans;  
  37. }  


[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. /* 
  2.  * manacher 算法  
  3.  * O(n)时间求字符串的最长回文子串 
  4.  * 需要先将字符串处理; 如"12212321" 改为"$#1#2#2#1#2#3#2#1#" 
  5.  * P[i]-1正好是原字符串中回文串的总长度; 
  6.  */  
  7. int id(0), mx(0); // id表示回文子串的中心, mx表示回文串的边界;  
  8. for(int i = 1; i < len; ++i) {  
  9.     p[i] = mx > i ? min(mx-i, p[2*id-i]) : 1;  
  10.     while(s[i+p[i]] == s[i-p[i]]) p[i]++;  
  11.     if(i+p[i] > mx) {  
  12.         mx = i+p[i];  
  13.         id = i;  
  14.     }  
  15. }  


大整数类模板:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. //基于vector<int>;  
  2. //字符串不自动处理前导0;  
  3. struct BigInteger{  
  4.     static const int BASE = 100000000;  
  5.     static const int WIDTH = 8;  
  6.     vector<int> s;  
  7.   
  8.     BigInteger(long long num = 0) { *this = num; }  
  9.     BigInteger& operator = (long long);  
  10.     BigInteger& operator = (string&);  
  11.   
  12.     BigInteger operator + (BigInteger &b);   //正数相加;  
  13.     BigInteger operator - (BigInteger &b);    //正数相减, 结果为正数;  
  14.     BigInteger operator * (BigInteger &b);  
  15.     BigInteger operator / (int b);   // 大整数间的除法能力有限,还写不出来;  
  16.     int operator % (int b);  
  17.   
  18.     bool operator < (const BigInteger &b) const;  //使用sort, map, set时需要定义;  
  19.     bool operator > (const BigInteger &b) const;  
  20.     bool operator <= (const BigInteger &b) const;  
  21.     bool operator >= (const BigInteger &b) const;  
  22.     bool operator != (const BigInteger &b) const;  
  23.     bool operator == (const BigInteger &b) const;  
  24. };  
  25.   
  26. BigInteger& BigInteger::operator = (long long num){  
  27.     s.clear();  
  28.     do{  
  29.         s.push_back(num % BASE);  
  30.         num /= BASE;  
  31.     }while(num > 0);  
  32.     return *this;  
  33. }  
  34.   
  35. BigInteger& BigInteger::operator = (string &str){  
  36.     s.clear();  
  37.     int x, len = (str.length()-1)/WIDTH + 1;  
  38.     for(int i = 0; i < len; ++i){  
  39.         int _end = str.length()-WIDTH*i;  
  40.         int start = max(0, _end-WIDTH);  
  41.         sscanf(str.substr(start, _end-start).c_str(), "%d", &x);  
  42.         s.push_back(x);  
  43.     }  
  44.     return *this;  
  45. }  
  46.   
  47. BigInteger BigInteger::operator + (BigInteger &b){  
  48.     BigInteger c;  
  49.     c.s.clear();  
  50.     for(unsigned i = 0, g = 0; ; ++i){  
  51.         if(g == 0 && i >= s.size() && i >= b.s.size()) break;  
  52.         int x = g;  
  53.         if(i < s.size()) x += s[i];  
  54.         if(i < b.s.size()) x += b.s[i];  
  55.         c.s.push_back(x % BASE);  
  56.         g = x / BASE;  
  57.     }  
  58.     return c;  
  59. }  
  60.   
  61. BigInteger BigInteger::operator - (BigInteger &b){  
  62.     BigInteger c;  
  63.     c.s.clear();  
  64.     for(unsigned i = 0, g = 0; ; ++i){   //bug;  
  65.         if(g == 0 && i >= s.size() && i >= b.s.size()) break;  
  66.         int x = g + s[i];  
  67.         if(i < b.s.size()) x -= b.s[i];  
  68.         if(x < 0) { c.s.push_back(BASE + x); g = -1; }  
  69.         else {c.s.push_back(x); g = 0; }  
  70.     }  
  71.     if(c.s.back() == 0) c.s.erase(c.s.end()-1);  
  72.     return c;  
  73. }  
  74.   
  75. BigInteger BigInteger::operator * (BigInteger &b){  
  76.     BigInteger c;  
  77.     c.s.clear();  
  78.     c.s.resize(s.size()+b.s.size()-1);  
  79.     long long g = 0;  
  80.     unsigned j;  
  81.     for(unsigned i = 0; i < s.size(); ++i){  
  82.         for(j = 0; j < b.s.size() ; ++j){  
  83.             long long x = g + static_cast<long long>(s[i])*b.s[j]+c.s[i+j];  
  84.             c.s[i+j] = x % BASE;  
  85.             g = x / BASE;  
  86.         }  
  87.         if(g != 0){  
  88.             if(i+j+1 > c.s.size()) c.s.resize(i+j+1);  
  89.             c.s[i+j] += g;  
  90.             g = 0;  
  91.         }  
  92.     }  
  93.     return c;  
  94. }  
  95.   
  96. BigInteger BigInteger::operator / (int b){  
  97.     BigInteger c;  
  98.     c.s.clear();  
  99.     c.s.resize(s.size());  
  100.     long long g = 0;  
  101.     for(int i = s.size()-1; i >= 0; --i){  
  102.         c.s[i] = (g*BASE + s[i])/b;  
  103.         g = g*BASE + s[i] - c.s[i]*b;  
  104.     }  
  105.     int clear_0 = s.size()-1;    //清除前导0;  
  106.     while(c.s[clear_0] == 0 && clear_0 > 0){  
  107.         c.s.erase(c.s.begin()+clear_0--);  
  108.     }  
  109.     return c;  
  110. }  
  111.   
  112. int BigInteger::operator % (int b){  
  113.     int remainder = 0;  //求余数;  
  114.     for(int i = s.size()-1; i >= 0; --i){  
  115.         remainder = ((remainder*BASE)%b + s[i]) % b;  
  116.     }  
  117.     return remainder;  
  118. }  
  119.   
  120. bool BigInteger::operator < (const BigInteger &b) const {  
  121.     if(s.size() != b.s.size()) return s.size() < b.s.size();  
  122.     for(int i = s.size()-1; i >= 0; --i)  
  123.         if(s[i] != b.s[i]) return s[i] < b.s[i];  
  124.     return false;  //相等;  
  125. }  
  126. bool BigInteger::operator > (const BigInteger &b) const { return b < *this; }  
  127. bool BigInteger::operator <= (const BigInteger &b) const { return !(*this > b); }  
  128. bool BigInteger::operator >= (const BigInteger &b) const { return !(*this < b); }  
  129. bool BigInteger::operator != (const BigInteger &b) const { return (*this < b) || (*this > b); }  
  130. bool BigInteger::operator == (const BigInteger &b) const { return !(b < *this) && !(*this > b); }  
  131.   
  132. ostream& operator << (ostream &out, const BigInteger &b){  
  133.     out << b.s.back();  
  134.     for(int i = b.s.size()-2; i >= 0; --i){  
  135.         char buf[10];  
  136.         sprintf(buf, "%08d", b.s[i]);  
  137.         out << buf;  
  138.     }  
  139.     return out;  
  140. }  
  141. istream& operator >> (istream &in, BigInteger &b){  
  142.     string str;  
  143.     in >> str;  
  144.     b = str;  
  145.     return in;  
  146. }  

猜你喜欢

转载自blog.csdn.net/wangzhuo0978/article/details/70244293