一些模板(按字典序排序)
一些模板的实现(按字典序排序)
文章目录
- 埃式筛法(优化)
- fft快速傅里叶变换:
- KMP
- 快速幂
- 扩展欧几里得
- 母函数:
- rmq(区间最值查询):
- 输入输出优化(面对一长串数字):
- Sunday算法(字符串配对)
- 通用外框:
- 希尔排序:
埃式筛法(优化)
应该比普通的快了一倍左右。
typedef long long ll;
int p[100000000];
int Max1=100000000;
void prime()
{p[2]=1;for(ll i=3;i<Max1;i+=2)p[i]=1;ll l=sqrt(Max1);for(ll i=3;i<l;i+=2){if(p[i]){ll k=2*i;for(ll j=3*i;j<=Max1;j+=k)p[j]=0;}}return ;
}
fft快速傅里叶变换:
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const int MAXN=1e7+10;
inline int read()
{char c=getchar();int x=0,f=1;while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f;
}
const double Pi=acos(-1.0);
struct complex
{double x,y;complex (double xx=0,double yy=0){x=xx,y=yy;}
}a[MAXN],b[MAXN];
complex operator + (complex a,complex b){ return complex(a.x+b.x , a.y+b.y);}
complex operator - (complex a,complex b){ return complex(a.x-b.x , a.y-b.y);}
complex operator * (complex a,complex b){ return complex(a.x*b.x-a.y*b.y , a.x*b.y+a.y*b.x);}//不懂的看复数的运算那部分
int N,M;
int l,r[MAXN];
int limit=1;
void fast_fast_tle(complex *A,int type)
{for(int i=0;i<limit;i++) if(i<r[i]) swap(A[i],A[r[i]]);//求出要迭代的序列 for(int mid=1;mid<limit;mid<<=1)//待合并区间的中点{complex Wn( cos(Pi/mid) , type*sin(Pi/mid) ); //单位根 for(int R=mid<<1,j=0;j<limit;j+=R)//R是区间的右端点,j表示前已经到哪个位置了 {complex w(1,0);//幂 for(int k=0;k<mid;k++,w=w*Wn)//枚举左半部分 {complex x=A[j+k],y=w*A[j+mid+k];//蝴蝶效应 A[j+k]=x+y;A[j+mid+k]=x-y;}}}
}
int main()
{int N=read(),M=read();for(int i=0;i<=N;i++) a[i].x=read();for(int i=0;i<=M;i++) b[i].x=read();while(limit<=N+M) limit<<=1,l++;for(int i=0;i<limit;i++)r[i]= ( r[i>>1]>>1 )| ( (i&1)<<(l-1) ) ;// 在原序列中 i 与 i/2 的关系是 : i可以看做是i/2的二进制上的每一位左移一位得来// 那么在反转后的数组中就需要右移一位,同时特殊处理一下复数 fast_fast_tle(a,1);fast_fast_tle(b,1);for(int i=0;i<=limit;i++) a[i]=a[i]*b[i];fast_fast_tle(a,-1);for(int i=0;i<=N+M;i++)printf("%d ",(int)(a[i].x/limit+0.5));return 0;
}
KMP
用来搞字符串配对的。
void GetNextval(char* p, int next[])
{ int pLen = strlen(p); next[0] = -1; int k = -1; int j = 0; while (j < pLen - 1) { if (k == -1 || p[j] == p[k]) { ++j; ++k; if (p[j] != p[k]) next[j] = k;else next[j] = next[k]; } else { k = next[k]; } }
}
int KmpSearch(char* s, char* p)
{ int i = 0; int j = 0; int sLen = strlen(s); int pLen = strlen(p); while (i < sLen && j < pLen) { if (j == -1 || s[i] == p[j]) { i++; j++; } else { j = next[j]; } } if (j == pLen) return i - j; else return -1;
}
快速幂
int fastPow(int a, int n){int base = a; int res = 1; while(n) {if(n & 1) //如果n的最后一位是1,表示这个地方需要乘res *= base; base *= base; //推算乘积,a2 --> a4 --> a8--> a16...n >>= 1; //n右移一位,把刚处理过的n的最后一位去掉}return res;
}
扩展欧几里得
求方程ax+by=gcd(a,b)的一个特解(x0, y0)
void extend_gcd(int a, int b, int &x, int &y){ //返回x,y,即一个特解(x0, y0)if(b==0) {x=1, y=0; return ;}extend_gcd(b, a%b, x, y);int tmp = x;x = y;y = tmp - (a/b)*y;
}
(1)判断ax+by=n有解
(2)用扩展欧几里得求 ax+by=gcd(a,b)的特解(x0, y0)
(3)在ax0+by0=gcd(a,b)的两边同乘n/gcd(a,b),得:
ax0n/gcd(a,b)+by0n/gcd(a,b)=n
(4)对照ax+by=n,一个特解是:
x0 n /gcd(a,b), y0 n /gcd(a,b)
特例1:
特例2:
逆元
int mod_inverse(int a, int m){int x, y;extend_gcd(a, m, x, y);return (m + x % m) % m; //x可能是负数
}
求逆元的另一个方法:费马小定理。
母函数:
通过三阶循环来实现,这里展示的是一个从x的一次方到二次方到三次方…n次方的母函数。
#include <iostream>
using namespace std;
const int _max = 10001;
int c1[_max], c2[_max];
int main()
{int nNum; int i, j, k;while(cin >> nNum){for(i=0; i<=nNum; ++i)//第一个式子 {c1[i] = 1;c2[i] = 0;}for(i=2; i<=nNum; ++i){for(j=0; j<=nNum; ++j)for(k=0; k+j<=nNum; k+=i){c2[j+k] += c1[j];}for(j=0; j<=nNum; ++j){c1[j] = c2[j];c2[j] = 0;}}cout << c1[nNum] << endl;}return 0;
}
rmq(区间最值查询):
这个是用来找一段数据内某个区间内的极大值或者极小值。
通过二进制来实现,十分巧妙。
代码实现:
#include<bits/stdc++.h>using namespace std;
#define MAX 10000
int dp[MAX][MAX],a[MAX],b[MAX],n;
void rmq()
{for(int i=0;i<n;i++)dp[i][0]=a[i];for(int j=1;(1<<j)<n;j++){for(int i=0;i+(1<<j)-1<n;i++){dp[i][j]=min(dp[i][j-1],dp[i+(1<<j-1)][j-1]);}}
}
int cz(int o,int p)
{int k=log2(p-o+1);return min(dp[o][k],dp[p-(1<<k)+1][k]);
}
int main()
{cin>>n;for(int i=0;i<n;i++)cin>>a[i];rmq();for(int i=0;i<n;i++){for(int j=i;j<n;j++){cout<<cz(i,j)<<' ';}cout<<endl;}
}
输入输出优化(面对一长串数字):
这主要针对的是一长串的数字(就是有许多的数字)(一般情况下也是这样一次给你好多组数据),这样输入可以节约很多时间。
inline int read()
{char c=getchar();int x=0,f=1;while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f;
}
void print(int x)
{if(x<0)putchar('-'),x=-x;if(x>9)print(x/10);putchar(x%10+'0');
}
Sunday算法(字符串配对)
比kpm与bm快。
int Sunday(const char *str1, const char *str2)
{int str1_len = strlen(str1);int str2_len = strlen(str2);int i = 0;int j = 0;enum{FALSE,TRUE};int Y = FALSE; if(str1 == NULL || str2 == NULL){return -1;}while(i < str1_len && j < str2_len){if(str1[i] == str2[j]){i++;j++; }else{int num = i - j + str2_len ;for(j = str2_len-1; j >= 0; j--){if(str1[num] == str2[j]){i = num - j;Y = TRUE;break;}}if(Y == FALSE){i = num + 1; }Y = FALSE;j = 0;}} if(i == str1_len){return -1;}elsereturn i - str2_len;
}
通用外框:
#include <bits/stdc++.h>using namespace std;typedef long long ll;
#define pc putchar
inline int read()
{char c=getchar();int x=0,f=1;while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f;
}
void print(int x)
{if(x<0)putchar('-'),x=-x;if(x>9)print(x/10);putchar(x%10+'0');
}
const int MAXN=1e7+10;
希尔排序:
这也是一种比较快的排序方法,所说有时比快排还要快,至于是不是真的我就不知道了,不过这个不能直接引用。
//函数功能,希尔排序算法对数字递增排序
//函数参数,数列起点,数列终点
void shell_sort(const int start, const int end) {int increment = end - start + 1; //初始化划分增量int temp{ 0 };do { //每次减小增量,直到increment = 1increment = increment / 3 + 1;for (int i = start + increment; i <= end; ++i) { //对每个划分进行直接插入排序if (numbers[i - increment] > numbers[i]) {temp = numbers[i];int j = i - increment;do { //移动元素并寻找位置numbers[j + increment] = numbers[j];j -= increment;} while (j >= start && numbers[j] > temp);numbers[j + increment] = temp; //插入元素}}} while (increment > 1);
}
一些模板(按字典序排序)相关推荐
- 【java】java反射机制,动态获取对象的属性和对应的参数值,并属性按照字典序排序,Field.setAccessible()方法的说明【可用于微信支付 签名生成】...
方法1:通过get()方法获取属性值 package com.sxd.test.controller;public class FirstCa{private Integer num;private ...
- 数据结构源码笔记(C语言):英文单词按字典序排序的基数排序
//实现英文单词按字典序排序的基数排序算法#include<stdio.h> #include<malloc.h> #include<string.h>#defin ...
- 函数模板案例_利用函数模板封装一个排序的函数,可以对不同数据类型数组进行排序 排序规则从大到小,排序算法为选择排序 分别利用char数组和int数组进行测试
案例描述: 利用函数模板封装一个排序的函数,可以对不同数据类型数组进行排序 排序规则从大到小,排序算法为选择排序 分别利用char数组和int数组进行测试 #include <iostream& ...
- mysql 实现按首字母字典序排序以及根据字段汉字首字母搜索
目录 mysql 实现按首字母字典序排序 mysql 根据字段汉字首字母搜索 mysql 实现按首字母字典序排序 mysql 一个表中的某一个字段存储的是人的名字 name 字符编码utf8_gene ...
- php 字符串 字典序序排序,C++ 怎么实现字典序排序法,自然排序
C++ 如何实现字典序排序法,自然排序 类似PHP的natcasesort函数,整了一天没有头绪. 数组是vector 排序前: [0] => IMG0.png [1] => IMG3.p ...
- java字符串字典排序_java实现对map的字典序排序操作示例
本文实例讲述了java实现对map的字典序排序操作.分享给大家供大家参考,具体如下: java中对map的字典序排序,算法验证比对微信官网https://mp.weixin.qq.com/wiki?t ...
- java string 字典序_[小白问题] Java 中路径 String 的字典序排序
最近在用不太熟悉的 java 写点项目,有个需求需要把以"."分隔的路径按照每个子路径的字典序排序,例如: python: arr = ["a.b.c", &q ...
- 函数模板案例—选择排序
案例描述: 1.利用函数模板封装一个排序算法,可以对不同数据类型数组进行排序 2.排序规则从大到小,排序算法为选择排序 3.分别利用char数组和int数组进行测试 #include<iostr ...
- java map字典序_java中对map的字典序排序
java中对map的字典序排序,算法验证比对微信官网https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115& ...
- 字典排序什么意思_字典序排序
查字典时,比如查单词 Love ,我们是从第一个字母L,开始查找,在A~Z开头中的单词中,不管是实际操作的二分查找还是别的方式查找,总能找到L打头的单词所在的位置范围,然后又在这个范围内开始查找O字母 ...
最新文章
- 操作系统内存管理-Linux版
- ios ionic3 跳转第三方地图 xcode加入白名单
- 【分治的典型应用:归并排序】
- Baidu_Location_SDK
- 离散数学及其应用傅彦pdf_《离散数学及其应用》第二章 计算与探索
- docker update
- php模板和框架,php模板和框架的区别的区别是什么
- redis-LinkedList
- PHP 大数据处理思路
- Revealing the Invisible with Model and Data Shrinking for Composite-database Micro-expression Recogn
- html如何插入一张图片,html如何插入图片
- Android系统默认Home应用程序 Launcher 的启动过程源代码分析
- 每年等额本金,计算复利的方法
- ubuntu将cuda卸载干净
- excel oracle 可为空,类似excel定位功能用不为空值填充为空列,用sql怎么实现
- HTTP 状态码 301 和 302 详解及区别——辛酸的探索之路
- SDWAN组网典型应用
- React中组件通信的几种方式
- css3 text-overflow制作固定区域的博客列表
- Win10打开游戏提示需要新应用打开此ms-gamingoverlay的解决方法
热门文章
- 头脑王者 物理化学生物
- 简道云、氚云、明道云们更讨中小企业欢心?
- cmake使用教程(十)-关于file,真是恍然大悟啊
- java NBA2010,关于一个NBA球队连续夺冠的SQL查询问题,解法很精妙~
- matlab解方程 中det,matlab中det函数
- 图形验证码识别接口(免费)
- 你知道wps删除空白页的方法吗?进来看看吧
- 计算机显卡驱动全部卸载,如何卸载显卡驱动重新安装?Win10卸载显卡驱动+重装显卡驱动的方法...
- java信息管理系统开题报告_开题报告-基于Java的学生信息管理系统设计.doc
- 【Stats】Jarque Bera test正态性检验