标签:oid ati 存在 ace bmp st3 operator 因子 方便
标签(空格分隔): 数论 @zhshh 听课笔记
2017-10-17
1.求phi
8407 12844
int phi(int n){
int ans=n;
// int num=n;//num用来标记flag的总数【详见下面POJ2773】
for(int i=2;i*i<=n;i++){
if(n%i==0){
ans-=ans/i;
while(n%i==0){
n/=i;
}
/* int m=1;
while(m*j<=n){
flag[m*j]=true;
}
*/
}
}
if(n!=1)ans-=ans/n;
return ans;
}
POJ2773
输入n,k求与n不互质的第k大整数
设数a,n若a,n不互质,即存在m是a,n因子,则m是a,n,n+a因子
同理若互质,n=k1m,a=k2m+b,则n+a=(k1+k2)*m+b;
因此1..n n+1..2n ....是否互质是循环的
在1..n内在去求第k % φ(n)个数即可
(用筛的方式(n的质因子)?)
后面两步还可以合并到了前面求phi时添加如下代码
int m=1;
while(m*j<=n){
flag[m*j]=true;
}
POJ3090
Visible Lattice Points
输入边长n,输出从(0,0)可以看到的所有点
IN:4 2 4 5 231(空格是换行符)
OUT:1 2 5 13 21 32549
样例:
快速幂
快速乘
快速幂/乘取模
矩阵快速幂(矩阵的处理如果定义结构体matrix并且重载了*和*=,代码与快速幂一样)
01矩阵快速幂
这些的思想一样,都是把func(type a,指数 b,int mod)的指数b位运算,达到log的速度,而其中的乘法/加法还是朴素算法。
加速是在幂(快速乘的乘)时进行的
long long poww(int a,int b){
long long ans=1,base=a;
if(a==0)return 0;
while(b){
if(b&1!=0){
ans*=base;
}
base*=base;
b>>=1;
}
return ans;
}
//这里的乘法是朴素乘法,快速是应用到了b的运算上
long long mul(int a,int b){ long long ans=0,base=a;//加法ans初始值为0 if(a==0)return 0; while(b){ if(b&1!=0){ ans+=base;//这步改成了加法 } base+=base;//同上改成加法 b>>=1; } return ans; }
最保险的方法是取模4次,不过在确定不会溢出的时候可以减少(提高速度)
long long poww_mod1(int a,int b,int c){
long long ans=1,base=a%c;
if(a==0)return 0;
while(b){
if(b&1!=0){
ans=(ans*base)%c;
}
base=(base*base)%c;
b>>=1;
}
return ans%c;
}
只有一个取模的写法,比如洛谷P1226 取余+快速幂 答案会溢出,AC前两个,WA后面4个
long long poww_mod2(int a,int b,int c){
long long ans=1,base=a;
if(a==0)return 0;
while(b){
if(b&1!=0){
ans=(ans*base)%c;
}
base=base*base;
b>>=1;
}
return ans;
}
定义:
#define n 5
struct matrix {
int x[n+1][n+1];
matrix() {
memset(x,0,sizeof(x));
}
void fill(int q) {
int maxx=sizeof(x)/sizeof(int);
int* p=&x[0][0];
while(maxx>0) {
*p=q;
p++;
maxx--;
}
}
};
写成了struct主要是为了方便重载运算符,以及各种初始化等,但是注意如果直接开很大的数组,会爆栈(例如上例#define n 1005
之后运行,程序立马崩溃)
矩阵的处理如果定义结构体matrix并且重载了*和*=,代码与快速幂一样
matrix operator *(matrix a,matrix b)
{
matrix ans;
ans.fill(0);
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) {
for(int k=1; k<=n; k++) {
ans.x[i][j]+=a.x[i][k]*b.x[k][j];
}
}
}
return ans;
}
因为x=x0*c/gcd ,所以整数解充要条件是c mod gcd==0
#include <iostream>
using namespace std;
int exgcd(int a,int b,int &x,int &y){
if(b==0){
x=1;
y=0;
return a;}//上面部分与gcd类似,后面根据上面证明可得x,y与x‘,y‘递推公式,不断回溯
int ret=exgcd(b,a%b,x,y);
int temp=x;
x=y;
y=temp-a/b*y;
return ret;
}
int main(){
int x,y;
int a=15;
int b=12;
int gcd=exgcd(a,b,x,y);//gcd为最大公约数
int c=63;
cout<<gcd;
if(c % gcd==0)cout<<endl<<"have int root";//因为方程的求解
cout<<endl<<x*c/gcd<<endl<<y*c/gcd;
cout<<endl<<b<<endl<<gcd;
int t=b/gcd;
cout<<endl<<x%t;
cout<<endl<<(x%t+t)%t;
}
void exgcd(a,b,&x,&y){
if( b==0)x=1,y=0;
else
ss(b,a%b,y,x),y-=x*(a/b)
}
shuashua树上差分
ZHxxxxxxx
标签:oid ati 存在 ace bmp st3 operator 因子 方便
原文地址:http://www.cnblogs.com/zhshh/p/7699312.html