zoukankan      html  css  js  c++  java
  • 背诵代码集合【更新至20200910 4days】

    20200910

    快速幂,树状数组

    long long quick_pow(long long a,long long b){
    	if(b==0) return a;
    	 else if(b%2==0){
    	 	b/=2;
    	 	return quick_pow(a,b)*quick_pow(a,b);
    	 }
    	 else {
    	 	b/=2;
    	 	return quick_pow(a,b)*quick_pow(a,b)*a;
    	 }
    }
    long long quick_pow(long long a,long long b,long long k){
    	if(b==0) return 1%k;
        if(b==1) return a%k;
         else if(b%2==0){
            b/=2;
            long long c=quick_pow(a,b,k)%k;
            return (c%k*c%k)%k;
         }
         else {
            b/=2;
            long long c=quick_pow(a,b,k)%k;
            return (c%k*c%k*a%k)%k;
         }
    }
    
    int gcd(int x,int y){
    	return x%y==0?y:gcd(y,x%y);
    }
    

    20200909

    线段树,素数筛,素数判断,质因数分解

    线段树(lazy标记)

    #include <cstdio>
    using namespace std;
    const int N=1e5+5;
    long long tree[4*N],a[N],m,n,x,y,z,d,lazy[4*N];
    void pushdown(int P,int l,int r)
    {
        int mid=(l+r)>>1;
        tree[P*2]+=(mid-l+1)*lazy[P];
        lazy[P*2]+=lazy[P];
        tree[P*2+1]+=(r-mid)*lazy[P];
        lazy[P*2+1]+=lazy[P];
        lazy[P]=0;
    }
    void buildtree(int P,/*编号*/int l,/*左*/int r/*右*/)//对于节点编号P两个子节点编为P*2,P*2+1 
    {
        if(l==r) {tree[P]=a[l]; return ;}
        int mid=(l+r)/2;
        buildtree(P*2,l,mid);
        buildtree(P*2+1,mid+1,r);
        tree[P]=tree[P*2]+tree[P*2+1];
    }
    void modifytree(int P,int l,int r,int ll,int rr,int x)//ll到rr加上x ;ll
    r为被修改区间的左右端点 
    {
        if(l==ll&&r==rr) {tree[P]+=x*(r-l+1);lazy[P]+=x;/*lazy标记*/ return;}
        pushdown(P,l,r);
        int mid=(l+r)/2;
        if(ll>mid) modifytree(P*2+1,mid+1,r,ll,rr,x);
        else if(mid>=rr) modifytree(P*2,l,mid,ll,rr,x);
        else modifytree(P*2,l,mid,ll,mid,x),modifytree(P*2+1,mid+1,r,mid+1,rr,x);
        tree[P]=tree[P*2]+tree[P*2+1];
    }
    long long asktree/*询问*/(int P,int l,int r,int askl,int askr)
    //在编号为P,范围是l到r的线段中,找到askl到askr这一段 
    {
        int mid=(l+r)/2;
        if(l==askl && r==askr) return tree[P];
        if(lazy[P]!=0) {
        	pushdown(P,l,r);}//ATTENTION
        
        if(mid>=askr) return asktree(P*2,l,mid,askl,askr) ;
        else if(mid<askl) return asktree(P*2+1,mid+1,r,askl,askr);
        return asktree(P*2,l,mid,askl,mid)+asktree(P*2+1,mid+1,r,mid+1,askr);
    	
    }
    int main()
    {
        scanf("%lld %lld",&n,&m);
        for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
        buildtree(1,1,n);
        //scanf("%d",&m);
        for(int i=1;i<=m;i++)
        {
        scanf("%lld",&x);
        if(x==1) scanf("%lld %lld %lld",&y,&z,&d),modifytree(1,1,n,y,z,d);
        if(x==2) scanf("%lld %lld",&y,&z),printf("%lld
    ",asktree(1,1,n,y,z));
        }
        return 0; 
    }
    

    素数

    1.素数筛法

    (O(n))

    #define maxn 1000010
    bool prime[maxn];
    int primes[maxn]
    int num_prime=0;
    void make_prime(){
      prime[0]=prime[1]=false;
      for(int i=2;i<=N;i++){
        if(prime[i]){
          primes[num_prime++]=i;
        }
        for(int j=0;j<num_prime &&i*primes[j]<N;j++){
          prime[i*primes[j]]=false;
          if(!(i%primes[j])){
    	break;
          }
        }
      }
      return ;
    }
    

    2.素数判断

    bool check(int n){
      int i;
      for(int i=2;i*i<=n;i++){
        if(n%i==0) return false;
      }
      return true;
    }
    

    3.质因数分解

    考虑到若(i)满足(n\% i=0),则有(n\% dfrac{n}{i}=0),所以可以仅枚举(i)从2到(sqrt{n})
    时间复杂度(O(sqrt{n}))

    void decom(int n){
      int i;
      vector<int> res;
      for(i=2;i*i<=n;i++){
        while(n%i==0){
          res.push_back(i);
          n/=i;
        }
      }
      for(i=0;i<res.size()-1;i++) printf("%d*",res[i]);
      printf("%d
    ",res.back());
     }
    

    如果事先已经用素数的线性筛法得到素数表了,那么有更快的方法进行质因数分解。
    素数的线性筛法中国每一个合数n仅仅在i枚举到n除以n最小的素因子时被筛出,因此可以得到每一个合数最小的质因数。
    对于要分解的合数n,先查表找到它最小的质因数,将其除掉,再找剩余的商种最小的质因数,依次操作,完成对n的分解。
    这个过程仅仅需要(O(log n))

    20200908

    逆元、KMP

    逆元

    代码:

    inv[1]=1;
    for(int i=1;i<=n;i++){
    	inv[i]=(p-p/i)*inv[p%i]%p;
    }
    

    前缀数组与( ext{KMP})

    求前缀数组代码find
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    int pi[10005];
    void find(char s[]){
      int len=strlen(s);
      for(int i=1;i<=len;i++){
        int j=pi[i-1];
        while(j>0 && s[i]!=s[j]) j=pi[j-1];
        if(s[i]==s[j]) j++;
        pi[i]=j;
      }
      return ;
    }
    char sl[10005];
    int main()
    {
      scanf("%s",sl);
      int len1=strlen(sl);
      find(sl);
      for(int i=0;i<len1;i++){
        printf("%d ",pi[i]);
      }
      return 0;
    }
    
    
    ( ext{KMP})代码
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    #define maxn 1000010
    int kmp[maxn];
    int la,lb,j;
    char a[maxn],b[maxn];
    int main(){
      scanf("%s %s",a+1,b+1);
      la=strlen(a+1);
      lb=strlen(b+1);
      for(int i=2;i<=lb;i++){
        while(j&&b[i]!=b[j+1]) j=kmp[j];
        if (b[j+1]==b[i]) j++;
        kmp[i]=j;
      }
      j=0;
      for(int i=1;i<=la;i++){
        while(j>0&&b[j+1]!=a[i]) j=kmp[j];
        if(b[j+1]==a[i]) j++;
        if(j==lb) {
          printf("%d 
    ",i-lb+1);j=kmp[j];
        }
      }
      for(int i=1;i<=lb;i++){
        printf("%d ",kmp[i]);
      }
      return 0;
    }
    

    20200907

    扩展gcd

    【同余方程】

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    void exgcd1(long long a,long long b,long long &x,long long &y){
      if(!b){
        x=1;y=0;return ;
      }
      exgcd1(b,a%b,x,y);
      int temp=x;
      temp=x;
      x=y;
      y=temp-(a/b)*y;
      return;
    }
    long long a,b,d,x,y;
    int main(){
      scanf("%lld %lld",&a,&b);
      exgcd1(a,b,x,y);
      printf("%lld",(x%b+b)%b);
      return 0;
    }
    
    

    重载运算符

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    int N;
    struct node{
      int len;
      int num[1005];
      friend node operator *(node a,int b){
        for(int i=1;i<=a.len;i++){
          a.num[i]*=b;
        }
        for(int i=1;i<=a.len;i++){
          if(a.num[i]>=10){
    	a.len=max(a.len,i+1);
    	a.num[i+1]+=a.num[i]/10;
    	a.num[i]%=10;
          }
        }
        return a;
      }
      friend node operator +(node a,node b){
        int lena=max(a.len,b.len);
        for(int i=1;i<=lena;i++){
         a.num[i]+=b.num[i];
        }
        for(int i=1;i<=lena;i++){
          if(a.num[i]>=10){
    	lena=max(lena,i+1);
    	a.num[i+1]+=a.num[i]/10;
    	a.num[i]%=10;
          }
        }
        a.len=lena;
        return a;
      }
      void print(){
        for(int i=len;i>=1;i--){
          printf("%d",num[i]);
        }
      }
      
    }tot,jie;
    int temp;
    int main(){
      scanf("%d",&N);
      tot.len=jie.len=1;
      jie.num[1]=1;
      for(int i=1;i<=N;i++){
        jie=jie*i;
        tot=tot+jie;
      }
      tot.print();
      return 0;
    }
    
    
    要做就做南波万
  • 相关阅读:
    swift制作framework过程
    Redis学习
    Mysql vs NoSql vs NewSql
    Mysql实践
    跨库分页解决方案[转]
    二分查找解题套路框架 [转]
    Service Mesh [转]
    Golang Case
    [转]分布式服务限流
    保险
  • 原文地址:https://www.cnblogs.com/liuziwen0224/p/13637468.html
Copyright © 2011-2022 走看看