当前位置: 首页 > news >正文

DP 凸性优化:wqs 二分

发现自己阅读量最高的 wqs二分 有点简略,而且有些地方是错的,所以就重构了一下,并加入了更多的例题。
前面基本上都是照搬的原来那篇文章。


介绍

wqs 二分最初由王钦石在他的 2012 年国家集训队论文中提出,也叫"带权二分",或者"dp凸优化",而从 IOI 2016 的 Aliens 题目开始,这种方法开始逐步在竞赛圈中有了一定的地位。在国内我们一般称为「wqs 二分」,而在国外一般称为「Alien Trick」。


特征

wqs 二分的题目一般有以下特点:

  • 题目内容形式为:有 \(n\) 个物品,从中选出 \(m\) 个,要求最后的权值最小/最大。
  • 直接 DP 设 \(f_{i,j}\) 表示前 \(i\) 个选出 \(j\) 个物品的话,时间复杂度无论如何都是 \(O(n^2)\) 及以上的。
  • 如果没有选 \(m\) 这个限制,那可以优化到更低复杂度,并且可以算出此时最优方案选的数的个数。
  • 答案关于选的物品个数具有凸性,即如果设 \(g(x)\) 表示选 \(x\) 个物品可以得到的最小/最大权值,那么 \(g(x)\) 的图像构成一个凸包。

当然 wqs 二分不止应用于 DP 题,具体看例题。


算法

大致流程

假设 \(g(x)\) 的图像为上凸包,此时我们要求最大值,不妨画一下 \(g(x)\) 的大致图像(当然其实我们是一个点都求不出来的):

假设我们现在用一条直线 \(y=kx+b\) 去切一个点 \((x,g(x))\),那么可以得到 \(g(x)=kx+b\),即这个点的坐标也可以表示成 \((x,kx+b)\)
又因为上凸包有个性质,一条斜率为 \(k\) 的直线在他与这个凸包的切点处截距最大,也就是说如果我们能求出这个最大截距,并知道此时的横坐标,就能知道那个切点的具体坐标了。
因为凸包的斜率是单调的,所以随着 \(k\) 的减小,切到的 \(x\) 也越大,所以可以二分这个 \(k\),然后根据切点的坐标去调整 \(k\) 直到切到 \((m,g(m))\) 为止。

现在的问题就是怎么求最大截距,因为我们压根不知道这个凸包长什么样子。
会发现 \(b = g(x)-kx\),定义 \(h(x) = g(x)-kx\),如果我们能以较低的复杂度求出最大的 \(h(x)\) 以及此时的 \(x\),也就求出了我们要的东西。
考虑给 \(h(x)\) 定义一个合理的意义,不难发现他其实就是给每个物品多加了一个 \(-k\) 的权值,选了这个物品就要 \(-k\)
而我们要求 \(h(x)\) 的最大值是没有限制要选多少个的,所以 DP 时只需要设一维即可,会更好求,具体的优化方法/求法因题目而异,在例题中会讲。
注意最后求 \(g(x)\) 时,要记得把 \(kx\) 加上。

实现细节——共线情形

当凸包上存在多个点共线的时候,我们二分的直线可能会同时切到很多点,如果我们最后求出来的 \((x,h(x))\) 是从中任取一个的话,会使得我们可能漏掉最终答案的位置。因此我们需要保证每次求出来的切点是所有可行切点中横坐标最小/最大的。以上凸壳为例,如果我们每次求出来的 \(x\) 是最小的,那么二分应该写的是 if(x<=mid) r=mid-1,更新答案; else l=mid+1;否则如果我们求出来的 \(x\) 是最大的,那么二分应该写的是 if(x>=mid) l=mid+1,更新答案; else r=mid-1
这是 wqs 二分最容易出错的点,在之后的例题中也会额外注明。

常见误区

  • 由于相邻两点的横坐标之差是 \(1\),所以此时斜率和差分没有区别,而当 \(g(x)\) 一定是整数时,斜率也一定是整数,因此我们二分也只需要二分整数域就一定可以切到要求的点;而当最后的答案可能是小数时,我们二分的斜率也应是实数域。
  • 假设我们最终二分出来的斜率为 \(k\),在 check 函数里求出来的是 \((x,h(x))\),那么假设我们在共线的时候取的是 \(x\) 最小的,则我们只能保证 \(x\le m\),即 \(x\) 不一定恰好就是 \(m\),但是我们可以知道用斜率为 \(k\) 的线去切,切在 \(x\) 上和切在 \(m\) 上的截距都是 \(h(x)\),因此最后的答案是 \(h(x)+km\),而不是 \(h(x)+kx\)

凸性证明

显然 wqs 二分最难的部分在于凸性的证明,其他部分都是套路和板子,以下是常见证明凸性的方法:

  • 感性理解/打表验证:很多时候在比赛时我们无法或者没有时间证明一个东西的凸性,此时常见的思路是猜测他具有凸性,之后通过感性理解/打表验证的方式非严谨地证明他的凸性。如例题 I。
  • 规约为费用流等凸的问题。如例题 III。
  • 通过 DP 转移方程归纳证明凸性。
  • 交换论证:以最小化问题为例,假设我们现在有了 \(g(x)\)\(g(x+2)\) 的方案构造,此时我们通过交换其中的元素构造出了两个 \(x+1\) 的方案,那么就证明了 \(2g(x+1)\le g(x)+g(x+2)\)\(g(x+1)-g(x)\le g(x+2)-g(x+1)\),所以函数是下凸的。如例题 IV。
  • 四边形不等式:对于带个数限制的区间分拆问题,朴素 DP 是 \(f(i,j)\) 表示前 \(i\) 个元素划分为 \(j\) 段的答案,转移为 \(f(i,j)=\min_{k<i}(f(k,j-1)+w(k+1,i))\),若代价函数 \(w(l,r)\) 满足四边形不等式,则 \(g(x)=f(n,x)\) 为关于 \(x\) 的下凸函数。证明见 oi-wiki 该页面。如例题 II。

例题

I. [国家集训队] Tree I

典中典。
恰好 \(need\) 条边考虑 wqs 二分,发现最小生成树的边权和关于白边数量是下凸的,所以直接 wqs 即可,check 函数只需要把每条白边的权值 \(-mid\) 然后跑 Kruskal。

共线情形的处理:我们要保证权值和相同的生成树求出来的是白边数量最小的,只需要 Kruskal 排序的时候把相同权值的黑边放白边前面即可。

凸性证明:我暂时还没有找到我能看懂又严谨的证明方法,所以这里给一下感性理解:考虑从初始最小生成树变到有 \(k\) 条白边的最小生成树的过程。我们每次都是选择一条白边(\(w_1\)),替换掉他的两端的树上路径上的最大黑边(\(w_2\)),并使边权之差 \(w_1-w_2\) 最小(如果初始最小生成树的白边数量大于 k 的话,那就是每次选一条黑边替换白边) 。如果在第 \(i\) 次替换后的增加量 \(>\)\(i+1\) 次替换后的增加量,我们可以交换这两次替换。因此最小生成树的边权和是关于白边数量下凸的。

点击查看代码
int n,m,k,tot,cnt,MST,fa[N];
struct Edge{int u,v,w,col;
}E[M];
int get(int x){return (x==fa[x])?x:(fa[x]=get(fa[x]));}
int val(Edge x,int mid){if(x.col) return x.w;return x.w-mid;
}
int check(int mid){sort(E+1,E+m+1,[&](Edge x,Edge y){if(val(x,mid)==val(y,mid)) return x.col>y.col;return val(x,mid)<val(y,mid);});MST=cnt=0;for(int i=0;i<n;i++) fa[i]=i;for(int i=1;i<=m;i++){int u=E[i].u,v=E[i].v,w=val(E[i],mid),col=E[i].col;if(get(u)==get(v)) continue;fa[get(u)]=get(v);MST+=w,cnt+=1-col;}return cnt;
}
signed main(){n=read(),m=read(),k=read();for(int i=1;i<=m;i++){int u=read(),v=read(),w=read(),col=read();E[i]={u,v,w,col};}int l=-100,r=100,mid,res;while(l<=r){mid=(l+r)>>1;if(check(mid)<=k) res=mid,l=mid+1;else r=mid-1;}check(res);printf("%d\n",MST+k*res);return 0;
}

II. 忘情

把式子变成 $((\sum_{i=1}^n x_i)+1)^2 $,设 \(S\) 为前缀和,那么朴素的 DP 是:
\(f_{i,j}\) 表示前 \(i\) 个数划分成 \(j\) 段的最小值,转移为 \(f_{i,j}=\min_{0\le k<i}(f_{k,j-1} + (S_i - S_k + 1)^2)\)
恰好 \(m\) 段考虑 wqs 二分,发现答案关于划分段数是下凸的。check 时一段的权值定义为 \(((\sum x_i)+1)^2 - K\),然后去掉段数限制,求最小答案。
考虑对这个新的问题 DP,设 \(dp_i\) 表示前 \(i\) 个数的最小值,\(dp_i=\min_{0\le j<i}(dp_j + (S_i-S_j+1)^2 - K)\),注意还需要记录当前分了多少段。
这是经典的斜率优化形式,可以用单调队列优化到 \(O(n)\),不会斜率优化的戳这里。
总时间复杂度 \(O(n \log n)\)

共线情形处理:显然下标越小最优情况下分的段数也越少,所以斜率优化时对于斜率相同的段我们选择保留而非弹出队列即可取到最小的转移点。(也可以看代码中的注释)

凸性证明:不难验证 \(w(l,r)=(S_r-S_{l-1}+1)^2\) 满足四边形不等式,所以是凸的。
当然也有感性理解:注意到
\((a+b+1)^2=a^2+b^2+1+2ab+2a+2b\)
\((a+1)^2+(b+1)^2=a^2+2a+b^2+2b+2\)
因此把一段拆成两段可以减少 \(2ab-1\)
而段数越多 \(a,b\) 越小,所以随着 \(m\) 的增加 \(g(m)\) 的值减小的幅度越来越小,函数下凸。

点击查看代码
int n,m,a[N],dp[N],g[N],dq[N],l,r;
int calc(int j){ return dp[j]+a[j]*a[j]-2ll*a[j];
} 
void check(int mid){l=1,r=0;dp[0]=0,g[0]=0;   dq[++r]=0;   for(int i=1;i<=n;i++){while(l<r && ( calc(dq[l+1]) - calc(dq[l]) ) < (2ll * a[i] * (a[dq[l+1]] - a[dq[l]]))) l++;  int j=dq[l];dp[i]=dp[j]+(a[i]-a[j]+1ll)*(a[i]-a[j]+1ll)+mid;g[i]=g[j]+1ll;while(l<r && ( calc(i) - calc(dq[r]) ) * ( a[dq[r]] - a[dq[r-1]]) < ( calc(dq[r]) - calc(dq[r-1] ) ) * ( a[i] - a[dq[r]] )) r--; 
//这里写 < 就是取最靠左的点;<= 就是取最靠右的点dq[++r]=i; }
}
signed main(){n=read(),m=read();for(int i=1;i<=n;i++) a[i]=read(),a[i]+=a[i-1];int l=0,r=inf,mid,ans=0;   //注意实际上斜率是负的,这里改成正的了,所以 check 函数内部是 +midwhile(l<=r){mid=(l+r)>>1;check(mid);if(g[n]<=m) r=mid-1,ans=mid;else l=mid+1; }check(ans);printf("%lld\n",dp[n]-ans*m);return 0;
}

III. CF739E Gosha is hunting

这个题存在二维 wqs 二分的写法,但是我不会,具体见 严谨的 wqs 二分 或 oi-wiki。但是,洛谷早期题解区的二维 wqs 二分全是错的(貌似目前还剩一篇),原因下面会有,注意区分。

不难列出期望 DP:\(f_{i,j,k}\) 表示前 \(i\) 个神奇宝贝,用 \(j\) 个宝贝球,\(k\) 个超级球的期望。
由于同时用两个球的概率 \(p+u-pu\) 一定 \(\ge p,u\) 所以全用了一定不劣,所以答案是 \(f_{n,a,b}\)
复杂度 \(O(n^3)\)

然后是发现 \(f_{n,a,i}\) 是关于 \(i\) 的上凸函数,感性理解不难,严谨证明如下。
考虑建费用流(\((w,c)\) 表示一条边的容量为 \(w\),费用为 \(c\)):

  1. 建立两个点 \(x,y\) 来限制选球的个数: \(S\to x (a,0)\)\(S\to y (b,0)\)
  2. \(x\to i (1,p_i)\)
  3. \(y\to i (1,u_i)\)
  4. \(i\to T\):连两条边,一条 \((1,0)\) 一条 \((1,-p_iu_i)\),由于 \(-p_iu_i\le 0\) 所以保证了在 \(i\) 的入流 \(= 1\) 时会优先走费用为 \(0\) 的边。
    最大费用最大流即为答案,根据费用流可证明在一维确定时,另一维有凸性。

费用流的凸性是从整体上的流量和费用来说的,所以无法证明两维同时具有凸性,这也是洛谷早期题解二维 wqs 二分错的原因。

所以可以 wqs 二分,每选一个超级球就要带上 \(-k\) 的代价,\(O(n^2)\) DP 出最优情况选的超级球的个数,直到这个个数 \(=b\),复杂度 \(O(n^2 \log n)\)

然后发现对于一个神奇宝贝 \(i\) 的四种情况:

  1. 只选宝贝球:\(p\)
  2. 只选超级球:\(u-k\)
  3. 同时选:\(p+u-pu-k\)
  4. 不选:\(0\)

由于宝贝球的最终使用个数是确定的(一定是 \(a\) 个),所以我们可以一开始钦定不用宝贝球。
那么一个神奇宝贝从不用宝贝球,到用宝贝球,增加量 \(\Delta=max(p,p+u-pu-k)-max(u-k,0)\)
由于 \(p\ge 0,p+u-pu-k\ge u-k\) 所以 \(\Delta\ge 0\)
于是我们按照 \(\Delta\) 排序,选最大的那 \(a\) 个使用宝贝球即可。
\(O(n\log^2 n)\),其实不难做到 \(O(n\log n)\)

共线情形处理不难,注意要实数域二分。

点击查看代码
int n,a,b;
double p[N],u[N],ans;
struct P{double deta;bool fl0,fl1;   
}A[N];
bool check(double k){ans=0;int cnt=0;for(int i=1;i<=n;i++){if(p[i]+u[i]-p[i]*u[i]-k>p[i]) A[i].deta=p[i]+u[i]-p[i]*u[i]-k,A[i].fl1=true;else A[i].deta=p[i],A[i].fl1=false;if(u[i]-k>0) A[i].deta-=u[i]-k,A[i].fl0=true,ans+=u[i]-k;else A[i].deta-=0,A[i].fl0=false;}		sort(A+1,A+n+1,[&](P x,P y){return x.deta>y.deta;});for(int i=1;i<=a;i++) ans+=A[i].deta,cnt+=A[i].fl1;for(int i=a+1;i<=n;i++) cnt+=A[i].fl0;return cnt<=b;
}
signed main(){ios::sync_with_stdio(false);cin.tie(0);cin>>n>>a>>b;for(int i=1;i<=n;i++) cin>>p[i];for(int i=1;i<=n;i++) cin>>u[i];double l=0,r=1,mid;while(r-l>eps){mid=(l+r)/2.0;if(check(mid)) r=mid;else l=mid;}printf("%.6lf\n",ans+l*b);	return 0;
}

IV. [ARC168E] Subsegments with Large Sums

看到恰好 \(k\) 段起手 wqs 二分但是他没有凸性。
考虑先去掉这 \(k\) 段拼起来一定要是原序列的限制,我们称一个子段合法当且仅当元素之和 \(\ge S\)
如果我们划分出了 \(x\) 段不相交的合法段,设他们的长度之和为 \(len\),则我们根据这 \(x\) 段可以去生成原问题的划分方案,且划分的段数的取值范围为 \([x,x+n-len]\)
所以合法当且仅当 \(x\le k\le x+n-len\),即 \(x\le k,len-x\le n-k\)
我们定义一个段的权值为 \(r-l\),设 \(f(x)\) 表示划分出 \(x\) 段不相交的合法段,每一段的权值和的最小值。
\(x\) 可行相当于 \(x\le k,f(x)\le n-k\),我们要求的答案就是最大的 \(x\)

接下来我们证明 \(f(x)\) 是一个下凸函数,证明来自官方题解。
首先 \(f(x)\) 是单增函数是显然的。
我们找出原序列中所有极短合法的子段,假设有 \(m\) 个,因为极短,所以不存在包含关系,所以我们按照左端点排序,右端点自然升序,我们顺次给他们编号 \(1,2,...,m\)
不难证明 \(f(x)\) 对应的那些段一定包含于这 \(m\) 段。
对于 \(f(p)\)\(f(p+2)\),我们设 \(x_1\le x_2\le \dots \le x_p\)\(f(p)\) 对应的那些段的编号,同理设 \(y_1\le y_2\le \dots \le y_{p+2}\)\(f(p+2)\) 对应的那些段的编号。
特殊的,我们规定 \(x_0=y_0=0,x_{p+1}=y_{p+3}=m+1\)
并且根据 \(f\) 的要求,第 \(x_i\) 段和第 \(x_{i+1}\) 是不相交的(\(y\) 同理)。
如果我们能找到一个 \(i (0\le i\le p)\) 满足 \(x_i\le y_{i+1}<y_{i+2}\le x_{i+1}\),那么我们可以构造出如下两个合法的 \(p+1\) 的方案:

  1. \(x_1,x_2,\dots , x_i,y_{i+2},\dots , y_{p+2}\)
  2. \(y_1,y_2,\dots , y_{i+1},x_{i+1},\dots , x_p\)

因为 \(y_{i+1}\ge x_i\)\(y_{i+2}\)\(y_{i+1}\) 不交,所以 \(y_{i+2}\) 也必定和 \(x_i\) 不交,同理 \(x_{i+1}\) 也必定和 \(y_{i+1}\) 不交,所以这两个方案是合法的。
因此 \(2f(i+1)\le f(i)+f(i+2)\)
然后就是证明为什么一定存在这样的 \(i\)
这个其实都不需要"第 \(x_i\) 段和第 \(x_{i+1}\) 是不相交的"这个限制,相当于一个数轴上除了两个端点 \(0,m+1\) 外中间还有 \(p\) 个关键点。然后你需要往上放 \(p+2\) 个点,不难发现如果不存在这样的 \(i\) 的话你最多只能往上放 \(p+1\) 个点。所以这样的 \(i\) 是一定存在的。

wqs 二分的内层 DP 是个简单的前缀 \(\min\) 优化。

最后是这题特殊的细节,这个 wqs 要求的是满足某个限制的 \(x\) 的最大值,而非某个给定的 \(x\)
所以当我们最后的斜率 \(k\) 切到一个斜率相同的区间时,由于最后的答案可能是某个中间的点,无法直接算出 \(x\)
我们可以先求出满足切到的区间的左端点合法的最大的 \(k\),此时右端点一定不合法,而这一段的斜率已经知道了,所以可以 \(O(1)\) 递推出下一项的 \(f\) 值。不断往后跳直到不合法就结束即可。

点击查看代码
int n,k,S,a[N];
PII f[N],pre[N];
bool check(int mid){f[0]={0,0},pre[0]={-1,0};for(int l=0,r=1;r<=n;r++){while(a[r]-a[l+1]>=S) l++;f[r]=f[r-1];if(a[r]-a[l]>=S) f[r]=min(f[r],mk(pre[l].fi+r-mid,pre[l].se+1));pre[r]=min(pre[r-1],{f[r].fi-(r+1),f[r].se});} return (f[n].fi+f[n].se*mid<=n-k)&&(f[n].se<=k);
}
signed main(){n=read(),k=read(),S=read();int maxn=0;for(int i=1,lst=0;i<=n;i++){a[i]=read()+a[i-1];if(a[i]-a[lst]>=S) maxn++,lst=i;}int l=0,r=n+5,mid,K;while(l<=r){mid=(l+r)>>1;if(check(mid)) K=mid,l=mid+1;else r=mid-1;}assert(check(K));int s=f[n].fi+f[n].se*K,x=f[n].se;while(x<=maxn&&x<=k&&s<=n-k) x++,s+=K;printf("%lld\n",x-1);return 0;
}

[IOI 2016] aliens

wqs 二分博客怎么能没有 aliens 呢。

不难发现如果要覆盖 \((x,y)\) 这个点必定要覆盖主对角线上区间 \([\min(x,y),\max(x,y)]\) 上的点,所以问题相当于变成了给你一个长度为 \(m\) 的数轴,数轴上有 \(n\) 个线段,要求选出至多 \(k\) 个区间(实际上一定会用恰好 \(k\) 个)使得每个线段都至少被一个区间包含。
显然有包含关系的线段可以去掉被包含的那条,所以把线段左端点排序右端点也升序,下面用 \(l_i,r_i\) 指代排序之后第 \(i\) 个线段的左右端点。
于是可以列出 DP,设 \(f_{i,j}\) 表示覆盖前 \(i\) 条线段,用了 \(j\) 个区间的最小代价,则 \(f_{i,j}=\min_{0\le k<i} f_{k,j-1}+w(k,i)\)
其中 \(w(a,b)=(r_b-l_{a+1}+1)^2-[a>0 \cap r_a\ge l_{a+1}](r_a-l_{a+1}+1)^2\),其中后半部分是减去重叠部分的贡献。
显然前半部分满足四边形不等式,而后半部分在四边形不等式中会被消掉,所以 \(w(a,b)\) 满足四边形不等式,所以是凸的,可以 wqs 二分。
check 内部和 II.忘情 一样是个简单的斜率优化,复杂度 \(O(n\log n)\)

点击查看代码
int n,m,k,cnt,w[N],dq[N],l,r;
PII f[N];
int qp(int x){return x*x;}
struct P{int l,r;
}t[N],a[N];
int x(int j){return 2*a[j+1].l;}
int y(int j){return f[j].fi+qp(a[j+1].l)-2*a[j+1].l-w[j];}bool check(int mid){f[0]={0,0};dq[l=r=1]=0;for(int i=1;i<=n;i++){while(l<r && a[i].r*(x(dq[l+1])-x(dq[l]))>(y(dq[l+1])-y(dq[l]))) l++;int j=dq[l]; f[i]=mk(f[j].fi+qp(a[i].r-a[j+1].l+1)-w[j]-mid,f[j].se+1);while(l<r && (y(i)-y(dq[r]))*(x(dq[r])-x(dq[r-1])) < (x(i)-x(dq[r]))*(y(dq[r])-y(dq[r-1]))) r--;dq[++r]=i;}return f[n].se<=k;
}
signed main(){n=read(),m=read(),k=read();for(int i=1;i<=n;i++){int x=read(),y=read();t[i]={min(x,y),max(x,y)};}sort(t+1,t+n+1,[&](P x,P y){return (x.l==y.l)?(x.r>y.r):(x.l<y.l);});for(int i=1,maxn=-1;i<=n;i++) if(maxn<t[i].r) maxn=t[i].r,a[++cnt]=t[i];swap(n,cnt);for(int i=0;i<n;i++) w[i]=(i>0&&a[i].r>=a[i+1].l)*qp(a[i].r-a[i+1].l+1);int l=-inf,r=0,mid,res;while(l<=r){mid=(l+r)>>1;if(check(mid)) l=mid+1,res=mid;else r=mid-1;}assert(check(res));printf("%lld\n",f[n].fi+res*k);return 0;
}

相关文章:

DP 凸性优化:wqs 二分

重构版:wqs 二分。发现自己阅读量最高的 wqs二分 有点简略,而且有些地方是错的,所以就重构了一下,并加入了更多的例题。 前面基本上都是照搬的原来那篇文章。介绍 wqs 二分最初由王钦石在他的 2012 年国家集训队论文中提出,也叫"带权二分",或者"dp凸优化&…...

浦东再添一所一流高校,上海交通大学医学院浦东校区正式启用

微信视频号:sph0RgSyDYV47z6快手号:4874645212抖音号:dy0so323fq2w小红书号:95619019828B站1:UID:3546863642871878B站2:UID: 3546955410049087 9月12日,上海交通大学医学院浦东校区正式启用,浦东再添一所一流高校。 添加图片注释,不超过 140 字(可选)浦东校区的启用…...

nccl study

https://lgd.gd/posts/2021/03/nccl/ https://blog.csdn.net/u014443578/article/details/136902252...

AI服务器公开招标大面积失败,中国联通“招”了个寂寞?

微信视频号:sph0RgSyDYV47z6快手号:4874645212抖音号:dy0so323fq2w小红书号:95619019828B站1:UID:3546863642871878B站2:UID: 3546955410049087为了查询三大运营商人工智能服务器的招投标信息,在工信部设立的“通信工程建设项目招标投标管理信息平台”上,搜索了一下有关…...

【GitHub每日速递 250916】2053 个 n8n 工作流曝光!365 种集成 + 可视化管理,效率直接拉满

原文:【GitHub每日速递 250916】2053个n8n工作流曝光!365种集成+可视化管理,效率直接拉满 Codebuff:开源AI编码助手,多模型协作胜Claude Code,还能深度自定义! codebuff 是一个通过终端生成代码的命令行工具。简单讲,它让你在终端里直接用AI生成代码,提升开发效率。适…...

每日一家公司职场内幕——龙旗科技(上海)

微信视频号:sph0RgSyDYV47z6快手号:4874645212抖音号:dy0so323fq2w小红书号:95619019828B站1:UID:3546863642871878B站2:UID: 3546955410049087公司简述:龙旗科技(Longcheer)成立于2002年,全球总部位于上海徐汇区,杭州还有一家做量化的龙旗科技,并非一家公司。龙旗…...

0129_迭代器模式(Iterator)

迭代器模式(Iterator) 意图 提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。 UML 图优点简化访问接口:提供统一的遍历接口,简化客户端代码 封装内部结构:隐藏聚合对象的内部表示,提高安全性 支持多种遍历:可以在同一聚合上实现多种遍历方式 开…...

HJ7 取近似值

描述 对于给定的正实数 x,输出其四舍五入后的整数。更具体地说,若 x 的小数部分大于等于 0.5,则输出向上取整后的数;否则输出向下取整后的整数。 【提示】 不同编译器版本、不同系统环境对待实数的精度处理不同,我们建议您使用在线编译器进行调试。 输入描述: 输入一个小…...

读人形机器人13艺术领域

读人形机器人13艺术领域1. 艺术领域 1.1. 艺术始终是人类灵魂的深刻表达,是一面反映我们最深情感、思想和经历的镜子 1.2. 超越语言、文化和时间的界限,连接着不同世代的人 2. 机器人创作艺术和音乐 2.1. 如今,AI生成的艺术和音乐已不再是单纯的实验性产物,它们正逐渐成为创…...

活动报名:Voice First!Demo Day@Voice Agent Camp,9.22,上海丨超音速计划 2025

听腻了那些类比电影《Her》却无法真实落地的语音 AI 畅想?来 Demo Day@Voice Agent Camp,见证 「Voice First」理念下,真正创意和商业潜力兼具的初创项目。9 月 22 日下午,上海西岸数字谷,欢迎加入我们,一同重塑人机实时互动体验。demo 项目均来自「超音速计划 2025Voice…...

Windows计算器:现代C++实现的多功能计算工具

Windows计算器是一个用C++和C#编写的现代Windows应用程序,提供标准、科学和程序员计算功能,以及各种单位换算和货币转换功能,采用高精度算术运算确保计算准确性。项目标题与描述 Windows计算器是一个现代化的Windows应用程序,使用C++和C#编写,预装在Windows操作系统中。该…...

使用 PySide6/PyQt6 实现系统图标的展示与交互

在 Python 桌面应用开发中,系统图标的展示与选择是提升用户体验的重要环节。PySide6 和 PyQt6 作为 Qt 框架的 Python 绑定,提供了 QFileIconProvider 等核心类来实现这一功能。本文将以代码实例演示如何在两个框架中实现系统图标的可视化呈现与交互处理。 基础环境搭建与核心…...

如何让Java的线程池顺序执行任务 ?

一、基础概念 Java中的线程池本身并不提供内置的方式来保证任务的顺序执行的,因为线程池的设计目的是为了提高并发性能和效率,如果顺序执行的话,那就和单线程没区别了。 但是如果被问到想要实现这个功能该怎么做,有以下两种方式 1、使用单线程线程池 我们可以使用 SingleTh…...

Git 提交排除文件夹方法总结

在 Git 中排除某个文件夹(使其不被提交到远程仓库)有几种方法。以下是主要的解决方案:方法一:使用 .gitignore 文件(推荐) 这是最标准的方法,适用于大多数情况。创建或编辑 .gitignore 文件:# 如果还没有 .gitignore 文件 touch .gitignore在 .gitignore 中添加要排除的…...

如何在 Ubuntu24.04 TLS 上安装 Kubernetes 集群 - Antonie

0-先决条件 在开始安装之前,请确保您的环境满足以下先决条件:Ubuntu 24.04 LTS 系统。 至少 4GB RAM 或更多。 至少 2 个 CPU 内核。 有 40 GB 可用磁盘空间。1- 环境准备 集群规划k8s-node-1(Master):10.15.0.132 k8s-node-2(Worker):10.15.0.133 k8s-node-3(Worker)…...

Jmeter的插件开发

一、Jmeter的启动流程 在说启动流程之前我们先来看看Jmeter源码的各个重要的包:components—包含与协议无关的组件,如可视化、断言等等。 core —JMeter的核心代码,包括所有的核心接口和抽象类。 examples —演示采样器如何使用新bean框架的例子(开发插件前可以好好看看该包…...

Educational Codeforces Round 182 (Rated for Div. 2)

A. Cut the Array 题意:把数组分成三段,使得每段和模\(3\)后的值都相同或者都不相同。 \(n\)很小,暴力枚举分段就行了。点击查看代码 #include <bits/stdc++.h>using i64 = long long;void solve() {int n;std::cin >> n;std::vector<int> a(n);for (int …...

java第二周课前提问

一、代码引入 public class Main {static void changeStr(String x) {x = "xyz";}static void changeArr(String[] strs) {for (int i = 0; i < strs.length; i++) {strs[i] = strs[i]+""+i;}}public static void main(String[] args) { String x = …...

java GC

java GC...

Redis最佳实践——性能优化技巧之监控与告警详解

一、监控体系构建1. 核心监控指标矩阵指标类别 关键指标 计算方式/说明 健康阈值(参考值)内存相关 used_memory INFO Memory 获取 不超过 maxmemory 的 80%mem_fragmentation_ratio 内存碎片率 = used_memory_rss / used_memory 1.0-1.5命中率 keyspace_hits INFO Stats 获取…...

week1

任务一,编码规范: 我在网上找到了华为公司C++编码规范,我摘下几点我觉得我应该注意的 1、程序块要采用缩进风格编写, 缩进的空格数为4个 2、不允许把多个短语句写在一行中, 即一行只写一条语句 3、 if、for、do、while、case、switch、default等语句自占一行, 且if、for、do…...

EF Core 与 MySQL:迁移和关系配置详解

EF Core 与 MySQL:迁移和关系配置详解 1. EF Core 中的关系类型 Entity Framework Core 支持三种主要的关系类型: 一对一关系 (One-to-One) 一个实体实例只与另一个实体实例相关联。例如:一个用户有一个用户资料。csharppublic class User {public int Id { get; set; }pub…...

《原子习惯》-读书笔记2

2025.09.15 Day2 1、目标和体系有什么不同?我最初是从“呆伯特漫画”的创作者斯科特亚当斯(Scott Adams)那里了解到两者的区别的。目标是关于你想要达到的结果,而体系是涉及导致这些结果的过程。2、争取每天都有进步是你走向成功唯一的方法。3、如果你想要得到更好的结果,那…...

CF1626D 题解

CF1626D 题解 貌似题解区没有这种解法。 题面 CF1626D Martial Arts Tournament - 洛谷 (luogu.com.cn) 思路 问题就是把 \(a\) 分成 \(3\) 个子集(可以为空),每两个子集里的数并不重复,把每个子集的大小补到 \(2^x\) 最少要补的数的个数。 先把 \(a\) 给排序,那么就可以转…...

Python 集合运算:并集、交集、差集全解析

在 Python 中,集合(set)是一种无序的、不包含重复元素的数据结构。集合提供了丰富的运算方法,包括并集、交集、差集等。这些运算在数据处理、数学计算和算法设计中非常实用。今天,就让我们一起深入学习 Python 集合的运算方法,并通过实例代码展示它们的使用。 一、集合的…...

第一周数据可视化作业

一、个人介绍 My name is Ou Qi. (🙂) 我性格阳光开朗,始终保持着对学习的热忱和对未知事物的探索欲,尤其从小就对数学有着浓厚兴趣 —— 课堂上会紧跟老师的思路深度思考,课后也常主动琢磨题型、尝试举一反三,在不断推导中把知识学扎实。 二、我的专业选择与学习历程 步…...

用 C++ + OpenCV + Tesseract 实现英文数字验证码识别

本文展示如何用 C++ 结合 OpenCV 做图像预处理,再调用 Tesseract OCR 识别验证码。适用于希望在高性能后端或本地服务里集成 OCR 的场景。方案包含: 更多内容访问ttocr.com或联系1436423940 环境与依赖安装 图像预处理(灰度、二值化、形态学去噪、放大) 使用 Tesseract API…...

java 第一节课课前提问

一、使用Java能编写的程序 企业级后端应用 Java 在企业级开发中占据重要地位,常被用于构建大型服务器端应用,如电商平台、银行交易系统、CRM(客户关系管理)系统等。这类应用通常需要处理高并发、复杂业务逻辑和海量数据,Java 凭借稳定的性能、丰富的企业级框架(如 Spring…...

二进制解码器、选通器和分配器

二进制解码器 3比特的二进制解码器可以由下图表示。每种组合方式对应着解码器的不同输出。3-8解码器可以用三个非门和三个与门构成解码器可以拼接起来组成更大的解码器,比如两个3-8解码器可以拼起来组成一个4-16解码器。选通器和分配器。 选通器 一个8选1的选通器如下图所示。…...

2025最新版 Photoshop软件免费下载安装完整教程(PS2025)超详细安装教程

Adobe Photoshop 2025 凭借升级的 AI 编辑功能、更优的图像处理效率,成为设计与摄影领域的热门工具。但不少用户在安装时,易因路径选择、安全软件拦截等问题卡壳。本教程聚焦安装全流程,从前期准备到后续配置,用清晰步骤帮你避开误区,顺利完成安装,快速解锁 PS 2025 的创…...

nac一键卸载软件脚本

将下面的代码保存为uninstall.sh: echo delete shit.app..need your root pwd; sudo rm -rf /Applications/dvc-manageproxy-exe.app; sudo rm -rf /Applications/LVSecurityAgent.app; echo script is fighting...; sudo chflags noschg /opt/LVUAAgentInstBaseRoot; sudo chf…...

交叉编译openharmony版本的openssh

sudo mkdir /systemsudo chmod 777 /system/export CC=aarch64-linux-gnu-gcc编译zlib./configure --prefix=/systemmake && make install 编译openssl./config linux-aarch64 --prefix=/system/ --openssldir=/system/etc/ssl --libdir=…...

为什么不建议在 Docker 中跑 MySQL

前言 今天我们来聊聊一个很有趣的话题:为什么我不建议在Docker中运行MySQL数据库? 有些小伙伴在工作中可能为了部署方便,习惯将所有组件都容器化,但数据库真的适合放在容器里吗? 今天就专门跟大家一起聊聊这个话题,希望对你会有所帮助。 一、容器化与数据库:天生的矛盾?…...

CFD

算例汇总 1、一维Sod激波管 2、二维平板 3、NACA0012 4、高马赫数喷流 5、双马赫反射 6、二维Riemann 7、二维Rayleigh-Taylor 8、TENO算例...

[MCP][05]Elicitation示例

Elicitation能让工具在关键时刻暂停执行,并向用户请求特定信息前言 如果你之前接触过LangGraph的"Human in the loop"概念,那么理解MCP的Elicitation机制就会容易很多。这两个功能非常相似,都是让AI在需要时停下来,礼貌地向人类寻求帮助或确认。 想象一下,当你正…...

Warsaw主题关闭导航条

\setbeamertemplate{headline}{}...

Python Socket网络编程(2)

进程:提供计算资源的单位 线程:真正工作的单位(cpu调度最小单元) GIL锁:全局解释器锁(是CPython解释器特有的,平时说的Python解释器一般都是CPython解释器,还有GPython等等) 让一个进程中同一时刻只能有一个线程可以被CPU调动。所以Python中应该是没有严格意义的多线程…...

PS2025安装包下载及PS2025安装包安装教程详细步骤(包含安装包下载链接)

在图像处理领域,Adobe Photoshop 一直占据着举足轻重的地位,而 PS 2025 更是汇聚前沿技术与实用功能,成为众多设计师与图像处理爱好者的得力工具。但初次安装这款软件,可能会因步骤繁杂、细节众多而让人感到棘手。别担心,本教程将以清晰、简洁的方式,带你一步步完成 PS 2…...

Nature Genetics | 本周最新文献速递

Multiancestry brain pQTL fine-mapping and integration with genome-wide association studies of 21 neurologic and psychiatric conditions 中文标题: 多祖先脑蛋白遗传调控解码!pQTL精细映射揭示神经精神疾病机制 关键词: 脑蛋白定量性状位点、精细映射、多祖先整合、…...

关于go里切片作为函数参数时是引用传递还是值传递

go语言中切片参数的值传递问题问题起因 写一道回溯算法题,把ans二维数组作为函数参数传入,想在函数里面,不停地append,最后返回ans 实际发现ans打印出来是空的,就很奇怪,因为我是事先分配好空间的,理论上不会发生扩容,底层数组是共用的,咋回事 func permute(nums []in…...

DRAN读写循环

DRAM读写循环 以一个8 * 8 的二维阵列为例子,假设部分存储单元为1,部分为0,现在要读写其中某一个cell的值。为了确定存储的位置,我们需要内存地址,为了传输内存地址,我们需要地址总线。8 * 8阵列一共有64个cell,我们需要6线地址总线,一共能表示64种二进制值。三根地址总…...

数据结构操作相关

堆 1、插入元素上滤每一次与父亲比较,满足大小就往上交换,直至不能往上为止。每次往上交换不会影响下面的性质2、删除/输出堆顶下滤假设大根堆,根节点换入末尾节点,每次先找出大儿子,若大儿子比自己大,则往下和他交换,直至不能往下为止。 3、建堆 1)初始为空,逐个inse…...

Neisbitt 不等式的证法

\(a,b,c\in R^+求证:\frac{a}{b+c}+\frac{b}{a+c}+\frac{c}{a+b}\geq\frac{3}{2}\) 证明: \(\because a,b,c\in R^+,\therefore\exists x,y,使得b=ax,c=ay\) \(\therefore LHS=\frac{1}{x+y}+\frac{x}{1+y}+\frac{y}{1+x}\) \(\therefore 令f(x,y)=\frac{1}{x+y}+\frac{x}{1+…...

端口转发神器Rinetd:轻量级安装与配置指南

什么是Rinetd? Rinetd(Redirection Internet Daemon)是一款轻量级的TCP端口转发工具,可以将来自一个IP地址和端口的连接转发到另一个IP地址和端口。它配置简单、资源占用少,是系统管理员和开发人员进行端口转发的理想选择。 Rinetd的主要特点轻量级:体积小,资源占用低 配…...

C语言中递归思想的应用

C语言中递归思想的应用 一、递归思想 在C语言中,函数是程序的基本单位,每个函数负责解决特定问题。但如果程序中出现n个相同的问题,就需要调用对应函数n次,这会导致程序冗长、可读性差。那么,有没有更简洁的解决方案呢? 答案是递归函数。递归函数并非万能,它更适用于解决…...

WITH RECURSIVE 递归公用表表达式(CTE)

生成一个从 1 到 12352 的连续数字序列SQL server SQL Server 对递归 CTE 有默认的递归深度限制(默认是 100),当递归次数超过这个限制时会报错。当远超默认限制时,需要在查询前使用 OPTION (MAXRECURSION 0) 来取消递归深度限制。WITH RECURSIVE num_sequence AS (SELECT 1…...

#java作业

1方法相关问题、 public class Main { static void changeStr(String x) { x = "xyz"; } static void changeArr(String[] strs) { for (int i = 0; i < strs.length; i++) { strs[i] = strs[i]+""+i; } } public static void main(String[] args) { …...

leetcode 3541. 找到频率最高的元音和辅音 便捷

leetcode 3541. 找到频率最高的元音和辅音 便捷pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace !…...

匿名递归与不动点组合子

先贴上 CS61A Homework 3 Recursion, Tree Recursion 中的最后一道思考题题面: ​Q6: Anonymous FactorialThis question demonstrates that its possible to write recursive functions without assigning them a name in the global frame.The recursive factorial function…...

Markdown学习Day01

Markdown学习第一天 【【狂神说Java】Java零基础学习视频通俗易懂】https://www.bilibili.com/video/BV12J41137hu?p=6&vd_source=e3ba980d960d7d6c98e4872bba8cf225 Markdown学习 二级标题 字体 her hus hou KLI 引用选择不需要辩护。分割线插图超链接 学Java 表格年级 班…...