数据结构进阶:前缀和与差分

news2024/10/7 8:28:22

数据结构进阶:前缀和与差分

  • 基础前缀和
  • 基础差分
  • 区间乘积
  • 前缀置换
  • 经典差分性质题目
  • 前缀和变种
  • 高次前缀和
  • 高维前缀和 (SOSDP)

蓝桥杯已经结束,打下来很难受。自己对于算法的掌握还是不够,遂继续开启博客书写,激励自己学习。本系列文章以牛客数据结构课程为基础,记录自己对于课程的理解和部分代码。供自己学习复习使用!

基础前缀和

int a[N],s[N];//前缀和数组
s[i]=s[i-1]+a[i];//s[i]表示a1+a2+...+ai
所以查询[l,r]的值之和就可以s[r]-s[l-1]

基础差分

差分数组b[i]=a[i]-a[i-1]
所以对差分数组求前缀和就可以得到原数组。
差分数组一般用来维护给一段区间加上或减去一直相同的值
比如给[l,r]区间的每个值都加上c
void insert(int l, int r, int c)
{
    b[l] += c;
    b[r + 1] -= c;
}
构造差分数组 for(int i=1;i<=n;i++) insert(i,i,a[i]);
或者 for(int i=1;i<=n;i++) b[i]=a[i]-a[i-1];
最后对b数组求一次前缀和就可以得到结果
    
对原数组差分后可以发现正数之和加上负数之和等于0

区间乘积

智乃酱的区间乘积
由于乘法运算也是可差分的。所以我们配合逆元便可以求区间乘积。

int n,m;
int a[N],s[N];
int qmi(int a,int k,int p){
    int res=1%p;
    a%=p;
    while(k){
        if(k&1) res=(LL)res*a%p;
        a=(LL)a*a%p;
        k>>=1;
    }
    return res;
}
void Showball(){
    cin>>n>>m;
    s[0]=1;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        s[i]=(LL)s[i-1]*a[i]%mod;
    }
    int l,r;
    while(m--){
        cin>>l>>r;
        cout<<(LL)s[r]*qmi(s[l-1],mod-2,mod)%mod<<endl;
    }
}

前缀置换

对于一些置换,如果我们也可以通过一些方式将它还原回去,那么我们就可以进行类似前缀和的操作,比如矩阵和矩阵求逆等等。
牛牛的猜球游戏

对于这道题目,我们发现对于每次交换操作,我们可以通过下标转换消去操作带来的影响,那么我们就可以进行类似前缀和的操作进行维护。

在这里插入图片描述

int n,m;
int s[N][10];
void Showball(){
    cin>>n>>m;
    for(int i=0;i<10;i++) s[0][i]=i;
    for(int i=1;i<=n;i++){
        int x,y;
        cin>>x>>y;
        memcpy(s[i],s[i-1],sizeof s[i]);
        swap(s[i][x],s[i][y]);
    }
    int l,r;
    while(m--){
        cin>>l>>r;
        int p[10];
        for(int i=0;i<10;i++) p[s[l-1][i]]=i;
        for(int i=0;i<10;i++) cout<<p[s[r][i]]<<" \n"[i==9];
    }
}

智乃酱的双塔问题
这个题目就涉及到了矩阵的前缀和操作。
贴一个大佬的题解

这里贴一个线段树做法

#include<bits/stdc++.h>
using namespace std;

const int N=1e5+10,M=2;
const int mod=1e9+7;
int n,m;

char s[N];
struct node{
    int l,r;
    int mat[M][M];
}tr[N*4];

void mul(int c[M][M],int a[M][M],int b[M][M]){
    int ans[M][M];
    memset(ans,0,sizeof ans);
    for(int i=0;i<M;i++){
        for(int j=0;j<M;j++){
            for(int k=0;k<M;k++){
                ans[i][j]=(ans[i][j]+1LL*a[i][k]*b[k][j])%mod;
            }
        }
    }
    memcpy(c,ans,sizeof ans);
}
void pushup(node &u,node &l,node &r){
   mul(u.mat,l.mat,r.mat);
}

void pushup(int u){
    pushup(tr[u],tr[u<<1],tr[u<<1|1]);
}

void build(int u,int l,int r){
    tr[u]={l,r};
    if(l==r){
       if(s[r]=='/'){
         auto &t=tr[u].mat;
         t[0][0]=t[0][1]=t[1][1]=1;
         t[1][0]=0;
       }else{
         auto &t=tr[u].mat;
         t[0][0]=t[1][0]=t[1][1]=1;
         t[0][1]=0;
       }
       return;
    }
    int mid=l+r>>1;
    build(u<<1,l,mid),build(u<<1|1,mid+1,r);
    pushup(u);
}

node query(int u,int l,int r){
    if(l<=tr[u].l&&tr[u].r<=r) return tr[u];
    int mid=tr[u].l+tr[u].r>>1;
    if(r<=mid) return query(u<<1,l,r);
    if(l>mid) return query(u<<1|1,l,r);
    node res;
    node left=query(u<<1,l,r);
    node right=query(u<<1|1,l,r);
    pushup(res,left,right);
    return res;
}
int main(){
    cin>>n>>m;
    for(int i=1;i<n;i++){
        cin>>s[i];
    }
    build(1,1,n-1);
    while(m--){
        int hs,ht,ps,pt;
        cin>>hs>>ht>>ps>>pt;
        cout<<query(1,hs,ht-1).mat[ps][pt]<<endl;
    }
    return 0;
}

经典差分性质题目

[NOIP2013]积木大赛
[NOIP2018]道路铺设
两道题目题意相似:都是有不同高度的积木,每次可以给一个区间加1,求最少操作构成积木。

差分性质
在这里插入图片描述
我们给原数组后面补一位0。这样我们发现差分数组的正数之和绝对值和负数之和绝对值相等。
而我们给一段区间加上1,相当于给差分数组一个值+1,一个值-1。那么最小的操作次数自然就为差分数组所有正数元素之和。

void Showball(){
   int n;
   cin>>n;
   vector<int> a(n+2),b(n+2);
   for(int i=1;i<=n;i++) cin>>a[i];
    int ans=0;
   for(int i=1;i<=n+1;i++){
    b[i]=a[i]-a[i-1];
    if(b[i]>0) ans+=b[i];
   }
   cout<<ans<<endl;
}

前缀和变种

前缀和+等差数列
对于一个等差数列 1 2 3 4 5 …
我们对其进行一次差分得到 1 1 1 1 1…
再进行一次差分即1 0 0 0 0 …
所以如果我们想要对于某一段区间加上 1,2,3,4,5,…
我们可以对它的二次差分数组该位加上1,然后求两次前缀和即可

前缀和+平方
同理 对于一个平方数列 1 4 9 16 25 …
我们对其进行一次差分得到 1 3 5 7 9 …
再进行一次差分得到 1 2 2 2 2 2…
再进行一次差分得到 1 1 0 0 0 0 …
所以如果我们想要对于某一段区间加上 1,4,9,16,25,…
我们可以对它的三次差分数组该位和下一位都加上1,然后求三次前缀和即可。

先来一道模板题
小w的糖果
三种操作分别对应普通区间加,区间加等差数列,区间加平方数列。
这里我们构建三个差分数组,然后进行对应操作即可。

#include<bits/stdc++.h>

using namespace std;

#define ff first
#define ss second
#define pb push_back
#define all(u) u.begin(), u.end()
#define endl '\n'
#define debug(x) cout<<#x<<":"<<x<<endl;

typedef pair<int, int> PII;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const int N = 1e5 + 10, M = 105;
const int mod = 1e9 + 7;
const int cases = 1;

int n,m;
LL d1[N],d2[N],d3[N];
void presum(LL d[]){
    for(int i=1;i<=n;i++){
        d[i]+=d[i-1];
        if(d[i]>mod) d[i]-=mod;
    }
}
void Showball(){
    cin>>n>>m;
    memset(d1,0,sizeof d1);
    memset(d2,0,sizeof d2);
    memset(d3,0,sizeof d3);
    int t,p;
    while(m--){
      cin>>t>>p;
      if(t==1){
        d1[p]++;
      }else if(t==2){
        d2[p]++;
      }else{
        d3[p]++;
        d3[p+1]++;  
      }
    }

    presum(d1);
    presum(d2);
    presum(d2);
    presum(d3);
    presum(d3);
    presum(d3);

    for(int i=1;i<=n;i++){
     cout<<(d1[i]+d2[i]+d3[i]+mod)%mod<<" \n"[i==n];
 }
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int T=1;
    if(cases) cin>>T;
    while(T--)
    Showball();
    return 0;
}

牛牛的Link Power I
题意:给你一个只含有0和1的字符串,两个1之间的距离为贡献。请你算出所有的贡献值之和。
举个例子:1010010
答案:2+5+3=10
我们算出每个1对于后面1的贡献,然后想加即可。
我们先看第一个1,然后我们发现第一个1对于后面的贡献分别为1 2 3 4 5 …
由此我们想到了上面讲到的前缀和+等差数列,我们可以对于每一个为1的位置加上一个等差数列。最后进行求前缀和。然后加上每一个1位置的值(也就是对应贡献)。即为答案。

int n;
LL sum[N];
string s;
void presum(){//求前缀和
    for(int i=0;s[i];i++){
        sum[i]+=sum[i-1];
        if(sum[i]>mod) sum[i]-=mod;
    }
}
void Showball(){
    cin>>n;
    cin>>s;
    for(int i=0;s[i];i++){
        if(s[i]=='1') sum[i+1]=1;//根据之前的性质,我们给差分数组的下一个位置+1。
    }

    presum();
    presum();//对差分数组求两次前缀和,得到原数组
    LL ans=0;
    for(int i=0;s[i];i++){
        if(s[i]=='1') ans+=sum[i];//对于等于1的位置,加上对应贡献
        if(ans>mod) ans-=mod;//取模
    }
    cout<<ans<<endl;
}

区间加多项式
之前我们处理的问题都是特殊情况,现在来考虑一般情况。给一段区间上加上一个多项式。我们还是按照之前的方式进行差分。可以发现对于任意一个最高次为k的多项式,我们对其进行k+1次差分,它一定会变成有限几项后面全为0的形式。那么我们就可以维护差分数组,然后求多次前缀和即可。

模板题:智乃酱的静态数组维护问题多项式

#include<bits/stdc++.h>

using namespace std;

#define ff first
#define ss second
#define pb push_back
#define all(u) u.begin(), u.end()
#define endl '\n'
#define debug(x) cout<<#x<<":"<<x<<endl;

typedef pair<int, int> PII;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const int N = 1e5 + 10, M = 105;
const int mod = 1e9 + 7;
const int cases = 0;

LL a[N],ki[N],coef1[N],coef2[N];
int n,m,q;
/*
在数组a的l,r区间加上一个多项式
然后前缀和。
P函数表示求长度为len的数组a,cnt次前缀和
D函数表示求长度为len的数组a,cnt次差分
f函数:a数组表示多项式系数,k表示最高次项
p函数:其实为-f(x+len)
*/
void P(LL a[],int len,int cnt=1){
  while(cnt--){

    for(int i=1;i<=len;i++){
        a[i]+=a[i-1];
        if(a[i]>=mod) a[i]-=mod;
    }
  }
}

void D(LL a[],int len,int cnt=1){
   while(cnt--){

    for(int i=len;i;i--){
        a[i]-=a[i-1];
        if(a[i]<0) a[i]+=mod;
    }
   }
}

LL f(int x,LL a[],int k){
    LL res=0;
    LL base=1;
    for(int i=k;i>=0;i--){
       res+=base*a[i]%mod;
       if(res>=mod) res-=mod;
       base=base*x%mod;
    }
    return res;
}

LL g(int x,LL a[],int k,int l,int r){
    return (mod-f(x+r-l+1,a,k))%mod;
}
void Showball(){
    cin>>n>>m>>q;
    for(int i=1;i<=n;i++) cin>>a[i];

    D(a,n,6);
    int l,r,k;
    while(m--){
      cin>>l>>r>>k;
      for(int i=0;i<=k;i++){
        cin>>ki[i];
      }

      for(int i=1;i<=10;i++){
        coef1[i]=f(i,ki,k);
        coef2[i]=g(i,ki,k,l,r);
      }
     
     D(coef1,10,6);
     D(coef2,10,6);
     
     for(int i=1;i<=10;i++){
        a[l+i-1]+=coef1[i];
        if(a[l+i-1]>=mod) a[l+i-1]-=mod;
        a[r+i]+=coef2[i];
        if(a[r+i]>=mod) a[r+i]-=mod;
     }
    }

    P(a,n,7);
    while(q--){
        int l,r;
        cin>>l>>r;
        cout<<(a[r]-a[l-1]+mod)%mod<<endl;
    }
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int T=1;
    if(cases) cin>>T;
    while(T--)
    Showball();
    return 0;
}

高次前缀和

快速的求k次前缀和,当k很大时,就需要用一些高级的东西进行优化,这里用的是卷积进行优化。原理尚不是很明白,先贴一个板子。
智乃酱的前缀和与差分

#include<bits/stdc++.h>
using namespace std;
namespace NTT
{
const long long g = 3;
const long long p = 998244353;
long long wn[35];
long long pow2(long long a, long long b)
{
	long long res = 1;
	while (b)
	{
		if (b & 1) res = res * a % p;
		a = a * a % p;
		b >>= 1;
	}
	return res;
}
void getwn()
{
	for (int i = 0; i < 25; i++) wn[i] = pow2(g, (p - 1) / (1LL << i));
}
void ntt(long long *a, int len, int f)
{
	long long i, j = 0, t, k, w, id;
	for (i = 1; i < len - 1; i++)
	{
		for (t = len; j ^= t >>= 1, ~j & t;);
		if (i < j) swap(a[i], a[j]);
	}
	for (i = 1, id = 1; i < len; i <<= 1, id++)
	{
		t = i << 1;
		for (j = 0; j < len; j += t)
		{
			for (k = 0, w = 1; k < i; k++, w = w * wn[id] % p)
			{
				long long x = a[j + k], y = w * a[j + k + i] % p;
				a[j + k] = (x + y) % p;
				a[j + k + i] = (x - y + p) % p;
			}
		}
	}
	if (f)
	{
		for (i = 1, j = len - 1; i < j; i++, j--) swap(a[i], a[j]);
		long long inv = pow2(len, p - 2);
		for (i = 0; i < len; i++) a[i] = a[i] * inv % p;
	}
}
void mul(long long *a, long long *b, int l1, int l2)
{
	int len, i;
	for (len = 1; len <= l1 + l2; len <<= 1);
	for (i = l1 + 1; i <= len; i++) a[i] = 0;
	for (i = l2 + 1; i <= len; i++) b[i] = 0;
	ntt(a, len, 0); ntt(b, len, 0);
	for (i = 0; i < len; i++) a[i] = a[i] * b[i] % p;
	ntt(a, len, 1);
}
};
const int MAXN = 300005;
const long long mod = 998244353;
int n;
long long a[MAXN], inv[MAXN], ki[MAXN], k;
void init(long long n)
{
	inv[0] = inv[1] = 1;
	for (long long i = 2; i <= n; i++)
	{
		inv[i] = ((mod - mod / i) * inv[mod % i]) % mod;
	}
	return;
}
void get_ki(long long k, int len)
{
	k = (k % mod + mod) % mod;
	ki[0] = 1;
	for (int i = 1; i < len; ++i)
	{
		ki[i] = ki[i - 1] * inv[i] % mod * ((k + i - 1) % mod) % mod;
	}
}
int main()
{
	NTT::getwn();
	init(100000);
	scanf("%d %lld", &n, &k);
	get_ki(k, n);

	for (int i = 0; i < n; ++i)
	{
		scanf("%lld", &a[i]);
	}
	NTT::mul(a, ki, n, n);
	for (int i = 0; i < n; ++i)
	{
		printf("%lld%c", a[i], i == n - 1 ? '\n' : ' ');
	}
	return 0;
}

高维前缀和 (SOSDP)

对于一般的二维前缀和都是采用容斥原理进行计算的。

s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j]

但是对于更高维度的就不太好写了。
这里推荐另外一种写法:

s[i][j]=a[i][j]
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
s[i][j]+=s[i-1][j];

for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
s[i][j]+=s[i][j-1];

也就是对每一维分别做前缀和
然后配合状态压缩,我们就可以进行高维前缀和了。操作如下:

 for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < (1<<n); ++j)
        {
            if (j & (1 << i))pre_sum[j] += pre_sum[j ^ (1 << i)];
        }
    }

例题:
智乃酱的子集与超集

#include<bits/stdc++.h>

using namespace std;

#define ff first
#define ss second
#define pb push_back
#define all(u) u.begin(), u.end()
#define endl '\n'
#define debug(x) cout<<#x<<":"<<x<<endl;

typedef pair<int, int> PII;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const int N = 1e5 + 10, M = 105;
const int mod = 1e9 + 7;
const int cases = 0;

int n,m;
LL pre_sum[1<<20],suf_sum[1<<20];
LL a[M];
void Showball(){
    cin>>n>>m;
    LL sum=0;
    for(int i=0;i<n;i++){
       cin>>a[i];
    }
    for(int i=0;i<(1<<n);i++){
        LL sum=0;
        for(int j=0;j<n;j++){
            if((i>>j)&1) sum^=a[j];
        }
        pre_sum[i]=sum;
        suf_sum[i]=sum;
    }

    for(int i=0;i<n;i++){
        for(int j=0;j<(1<<n);j++){
            if(j&(1<<i)) pre_sum[j]+=pre_sum[j^(1<<i)];
            else suf_sum[j]+=suf_sum[j^(1<<i)];
        }
    }
    int k;
    while(m--){
      cin>>k;
      LL p=0;
      for(int i=0;i<k;i++){
         int x;
         cin>>x;
         p|=(1<<(x-1));
      }
      cout<<pre_sum[p]<<" "<<suf_sum[p]<<endl;
    }

}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int T=1;
    if(cases) cin>>T;
    while(T--)
    Showball();
    return 0;
}

完结撒花~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/425662.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FinClip 云开发实践(附小程序demo)

在开发一个小程序时&#xff0c;除了考虑界面功能逻辑外&#xff0c;还需要后端的数据支持&#xff0c;开发者需要提前考虑服务器、存储和数据库等相关需求的支持能力&#xff0c;此外还可能需要花费时间精力在部署应用、和依赖服务的建设上。 ​ 因此&#xff0c;腾讯小程序为…

【Java】类和对象详解

1. 类和对象 1.1 类和对象的理解 客观存在的事物皆为对象 &#xff0c;所以我们也常常说万物皆对象。 类 类的理解 类是对现实生活中一类具有共同属性和行为的事物的抽象类是对象的数据类型&#xff0c;类是具有相同属性和行为的一组对象的集合简单理解&#xff1a;类就是对…

Dva.js(基础、简单例子解读)

简单介绍一下 近期在做react项目时&#xff0c;看到项目中数据的公共存储用的Dva.js&#xff0c;整体的代码结构看起来和vuex差不多&#xff0c;这两天趁着刚忙完&#xff0c;利用工作之余的时间空隙&#xff0c;大致了解了dva的基础理论&#xff0c;代码结构应用&#xff0c;参…

Qt 项目A调用项目B方法(项目架构管理)

前言 项目开发中&#xff0c;如果项目比较大&#xff0c;大多采用多项目的方式&#xff0c;主要是为了方便代码管理&#xff0c;也更开发变得更加方便。操作如下&#xff1a; 注&#xff1a;我用的版本是Qt 5.12.3 一、建立项目目录 要求&#xff1a; 1、项目A为主&#xff…

FreeRTOS中的任务与任务切换(笔记)

目录任务的定义栈和任务栈任务控制块任务初始化函数初始化任务栈任务创建函数pxTopOfStack任务列表初始化将任务插入到就绪列表中调度器xPortStartScheduler() 函数prvStartFirstTask()函数 &#xff08;该函数是偏硬件底层的函数&#xff0c;用汇编语言编写&#xff0c;在port…

中电金信「财务公司核心系统白皮书」正式发布!

随着数字技术的深度应用&#xff0c;数字化转型正迎来新一轮变革。如何促进企业战略转型&#xff0c;助力企业发展提质增效&#xff0c;以标准化、数字化、精细化支撑企业实现高质量发展&#xff0c;已成为财务公司数字化转型的重要课题。 为推进财务公司数字化转型工作要求&a…

恢复照片软件推荐,照片恢复就这么做!

案例&#xff1a;好用的恢复照片软件 【作为一名摄影博主&#xff0c;我每天拍的照片太多了&#xff0c;在筛选的时候总是容易错删重要的照片&#xff0c;大家有什么比较好的照片恢复软件或方法可以推荐吗&#xff1f;万分期待!】 随着数字化时代的发展&#xff0c;人们越来越…

QPixmap存在的坑,内存泄漏

QPixmap加载图片的时候&#xff0c;会把图片数据加入到QPixmapCache缓冲区上 如果多次加载&#xff0c;那么内存会被吃掉越来越多 本意QPixmap是用于显示需要比较快的地方&#xff0c;和硬件关联 QPixmap变量之间的赋值&#xff0c;并不会构造新的图片数据内存&#xff0c;而…

基于Eclipse下使用arm gcc开发GD32调用printf

系列目录 第一章 xxx 目录 系列目录 文章目录 文章目录 系列文章目录前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结前言 开发环境&#xff1a;Eclipse代替Keil&#xff0c;IAR 开发平台&#xff1a;GD32 开发编译器&#xff1a;arm-none-eabi- …

Adobe Acrobat Pro DC 2022的系统要求

Adobe Acrobat Pro DC 2022是一款功能强大的PDF编辑和管理软件。它可以帮助用户创建、编辑、转换、签署和共享PDF文档&#xff0c;并提供了多种工具和功能来优化文档的可访问性、安全性和可靠性。 Adobe Acrobat Pro DC 2022功能特色&#xff1a; 创建和编辑PDF文档&#xff1…

《低代码PaaS驱动集团企业数字化创新白皮书》-大型集团企业的数字化困局

大型集团企业的数字化困局 现状 /态势&#xff1a;数字化发展动力&#xff0c;构建数字化竞争力&#xff0c;实现敏捷的运营、治理、决策、体验 数字化转型大势所趋 全球化地缘政治紧张局势&#xff0c;供应链、通货膨胀、劳动力短缺以及新冠疫情全球大流行更增加了人们对全球…

HLS_OPENCV库的安装

借此机会来记录一下OPENCV库的安装:   首先需要知道的是说起OPENCV库有两种&#xff0c;一种是OPENCV库&#xff0c;还有一种是Xilinx官方自己的OPENCV库&#xff0c;前者可以用来在HLS中进行仿真&#xff0c;无法进行综合&#xff0c;而后者则是可以进行综合的。现将两种库的…

【综述型论文】图神经网络总结

文章目录图神经网络基于模型结构分类的图神经网络1. 循环图神经网络&#xff08;ResGNNs&#xff09;2. 卷积图神经网络基于谱域的ConvGNNs&#xff08;Spectral-based ConvGNNs&#xff09;基于空域的ConvGNNs&#xff08;Spatial-based ConvGNNs&#xff09;谱域图卷积模型和…

Python遥感开发之FY的批量处理

Python遥感开发之FY的批量处理0 FY遥感数据1 批量提取数据2 批量拼接TIF数据3 批量HAM转WGS投影&#xff08;重要&#xff09;4 批量掩膜裁剪介绍FY数据的格式&#xff0c;以及FY数据的批量提取数据、批量拼接数据、批量投影转换、批量掩膜裁剪等操作。本博客代码参考《 Hammer…

MySQL SQL优化 【建议熟读并背诵】

插入数据 批量插入数据 insert into tb_test values(1,Tom),(2,Cat),(3,Jerry);手动控制事务 start transaction; insert into tb_test values(1,Tom),(2,Cat),(3,Jerry); insert into tb_test values(4,Tom),(5,Cat),(6,Jerry); insert into tb_test values(7,Tom),(8,Cat…

在Windows中使用Linux命令安装这款软件就可以

由于平时经常使用Linux命令&#xff0c;所以导致在Windows的cmd中输入命令的时候经常打错&#xff0c;提示不是内部或外部命令&#xff0c;也不是可运行的程序。 那么有办法将补全cmd命令&#xff0c;使Linux中的命令在Windows中也能使用呢&#xff1f; 下面我来讲解如何在Win…

微服务架构-服务网关(Gateway)-服务网关在微服务中的应用

服务网关在微服务中的应用 我们将目光转向Spring Cloud应用的外围&#xff0c;讨论微服务架构下的各个模块如何对外提供服务。 1、对外服务的难题 微服务架构下的应用系统体系很庞大&#xff0c;光是需要独立部零的基础组件就有注册中心、配置中心和服务总线、Turbine异常聚…

【版本控制】Github同步Gitee镜像仓库自动化脚本

文章目录Github同步Gitee镜像仓库自动化脚本前言什么是Hub Mirror Action&#xff1f;1.介绍2.用法配置步骤1.生成密钥对2.GitHub私钥配置3.Gitee公钥配置4.Gitee生成私人令牌5.Github绑定Gitee令牌6.编写CI脚本7.多仓库同步推送8.定时运行脚本总结Github同步Gitee镜像仓库自动…

Softmax和Cross Entropy Loss在分类问题中的作用

本文以三分类神经网络为例&#xff0c;讲解Softmax和Cross Entropy Loss在分类问题中的作用。 首先&#xff0c;对类别标签进行一位有效编码&#xff1a; y[y1,y2,y3]Ty[y_{1},y_{2},y_{3}]^{T}y[y1​,y2​,y3​]T yi{1,if(iy)0,otherwisey_{i}\left\{\begin{matrix} 1 ,& …

形式语言和自动机总结----正则语言RE

第3-4章正则表达式 正则表达式的设计举例 正则表达式的运算 正则表达式的优先级 举例 1.倒数第三个字符是1 &#xff08;01)*1(01)(01) 2.不含有连续的0 &#xff08;101&#xff09;*&#xff08;0&#xff09; 3.含有000 &#xff08;01&#xff09;*000&#xff08;01&a…