前言

Hall定理:一张二分图有完美匹配(即最大匹配为 \(\min\{|X|,|Y|\}\) )

当且仅当任意一个点集 \(X'\) 与所有能直接到达 \(X'\) 的点集 \(Y'\),

也就是 \(X'\) 与邻域 \(N(X')\) 所组成的导出子图有完美匹配

也就是 \(\forall X',|X'|\leq |N(X')|\)

推论:一张二分图的最大匹配为 \(\min\{|X|-\max\{|X'|-|Y'|\},|Y|\}\)


HDU 6667 Roundgod and Milk Tea

题目

有 \(n\) 个班级(\(n\leq 2\times 10^5\)),每个班级有 \(a_i\) 名学生,该班共生产 \(b_i\) 杯奶茶,

每个学生只能购买其它班级的奶茶,问最多有多少个学生能够喝到奶茶


分析

可以发现直接建图就是一个二分图求最大匹配,但肯定会超时。

根据推论,考虑让 \(|X'|-|Y'|\) 尽量大。

分类讨论一下,只有 \(X'\) 仅为一个班级时,这个值最大。

那么直接 \(O(n)\) 求 \(\max\{a_i-(s-b_i)\}\) 即可


代码

#include <cstdio>
#include <cctype>
using namespace std;
const int N=200011;
typedef long long lll;
int n,a[N],b[N]; lll stu,tea,ans;
int iut(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
void print(lll ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
lll min(lll a,lll b){return a<b?a:b;}
lll max(lll a,lll b){return a>b?a:b;}
int main(){
for (int T=iut();T;--T){
n=iut(),ans=stu=tea=0;
for (int i=1;i<=n;++i){
a[i]=iut(),b[i]=iut();
stu+=a[i],tea+=b[i];
}
for (int i=1;i<=n;++i)
ans=max(ans,a[i]-(tea-b[i]));
print(min(stu-ans,tea)),putchar(10);
}
return 0;
}

AT2645 [ARC076D] Exhausted?

题目

有 \(n\) 个人,\(m\) 把椅子,每个人只愿意坐在第 \(l_i\) 把或其前面或者第 \(r_i\) 把或其后面,

问至少添加多少张椅子才能使所有人就坐。\(n,m\leq 2*10^5\)


分析(反悔贪心)

可以发现答案就是 \(n-\) 最大匹配,但是由于条件的特殊性可以用反悔贪心实现。

按 \(r_i\) 降序,再 \(l_i\) 升序的顺序排序,用一个双指针从后往前扫描可用的椅子。

如果后面的椅子不够用,那么抽出其中 \(l_i\) 最大的一个人的椅子给当前人使用,可以用大根堆实现。

然后没有椅子的人再从前往后扫描可用的椅子,没有椅子就只能添加椅子。


代码(反悔贪心)

#include <cstdio>
#include <cctype>
#include <algorithm>
#include <queue>
using namespace std;
const int N=200011;
struct rec{int l,r;}a[N];
int n,m,tot,ans,b[N],L,R;
priority_queue<int>q;
int iut(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
bool cmp(rec x,rec y){
if (x.r!=y.r) return x.r>y.r;
return x.l<y.l;
}
int main(){
n=iut(),R=m=iut(),L=1;
for (int i=1;i<=n;++i) a[i]=(rec){iut(),iut()};
sort(a+1,a+1+n,cmp);
for (int i=1;i<=n;++i){
q.push(a[i].l);
if (R>=a[i].r&&L<=R) --R;
else b[++tot]=q.top(),q.pop();
}
sort(b+1,b+1+tot);
for (int i=1;i<=tot;++i)
if (L<=b[i]&&L<=R) ++L; else ++ans;
return !printf("%d",ans);
}

分析(Hall定理)

根据推论,答案为 \(\max\{|X'|-|Y'|,|X|-|Y|\}\)

后面单独写出来主要是对 \(n-m\) 取最大值。

观察到这个邻域就是区间的并,比较难求,将其补集转化为区间的交。

那也就是令 \(R-L-1+|X'|-m\) 最大,其中 \(X'\) 中的任意区间满足 \(l_i\leq L 且 R\leq r_i\)

那么按照 \(l_i\) 升序排序,然后枚举左端点,用线段树维护最大值 \(R+|X'|\) 即可。


代码(Hall定理)

#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;
const int N=200011;
struct rec{int l,r;}a[N];
int w[N<<2],lazy[N<<2],n,m,ans;
int iut(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
int max(int a,int b){return a>b?a:b;}
bool cmp(rec x,rec y){
if (x.l!=y.l) return x.l<y.l;
return x.r>y.r;
}
void build(int k,int l,int r){
w[k]=r;
if (l==r) return;
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
}
void update(int k,int l,int r,int x,int y){
if (l==x&&r==y) {++w[k],++lazy[k]; return;}
int mid=(l+r)>>1;
if (lazy[k]){
lazy[k<<1]+=lazy[k],lazy[k<<1|1]+=lazy[k];
w[k<<1]+=lazy[k],w[k<<1|1]+=lazy[k],lazy[k]=0;
}
if (y<=mid) update(k<<1,l,mid,x,y);
else if (x>mid) update(k<<1|1,mid+1,r,x,y);
else update(k<<1,l,mid,x,mid),update(k<<1|1,mid+1,r,mid+1,y);
w[k]=max(w[k<<1],w[k<<1|1]);
}
int query(int k,int l,int r,int x,int y){
if (l==x&&r==y) return w[k];
int mid=(l+r)>>1;
if (lazy[k]){
lazy[k<<1]+=lazy[k],lazy[k<<1|1]+=lazy[k];
w[k<<1]+=lazy[k],w[k<<1|1]+=lazy[k],lazy[k]=0;
}
if (y<=mid) return query(k<<1,l,mid,x,y);
else if (x>mid) return query(k<<1|1,mid+1,r,x,y);
else return max(query(k<<1,l,mid,x,mid),query(k<<1|1,mid+1,r,mid+1,y));
}
int main(){
n=iut(),m=iut();
for (int i=1;i<=n;++i) a[i]=(rec){iut(),iut()};
sort(a+1,a+1+n,cmp);
build(1,1,m+1);
for (int i=1;i<=n;++i){
update(1,1,m+1,a[i].l+1,a[i].r);
ans=max(ans,query(1,1,m+1,a[i].l+1,a[i].r)-a[i].l-1-m);
}
return !printf("%d",max(ans,n-m));
}

CF981F Round Marriage

题目

\(n\) 个新郎和 \(n\) 个新娘围成一个环,长度为 \(L\),第 \(i\) 个新郎位置为 \(a_i\),

第 \(i\) 个新娘位置为 \(b_i\),需要将他们两两配对,最小化新郎和新娘距离的最大值。


分析

二分答案转为判定是否为最大匹配,直接用 \(Hall\) 定理就是要保证 \(|X'|\leq |Y'|\)

在本题即转化为 \(j-i+1\leq r-l+1\),也就是要保证 \(r-j\geq \max\{l-i\}\)

将环断为链,然后用双指针维护即可

由于两个都是环,所以让新郎复制一份,新娘先复制一份,在头尾各复制一份


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;
const int N=200011; typedef long long lll;
lll a[N<<1],b[N<<2]; int n,len;
int iut(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
int max(int a,int b){return a>b?a:b;}
bool check(int mid){
int head=1,tail=1,mx=0xcfcfcfcf;
for (int i=1;i<=2*n;++i){
while (head<=4*n&&b[head]<a[i]-mid) ++head;
while (tail<=4*n&&b[tail]<=a[i]+mid) ++tail;
mx=max(mx,head-i);
if (tail-i-1<mx) return 0;
}
return 1;
}
int main(){
n=iut(),len=iut();
for (int i=1;i<=n;++i) a[i]=iut();
for (int i=1;i<=n;++i) b[i]=iut();
sort(a+1,a+1+n),sort(b+1,b+1+n);
for (int i=1;i<=n;++i) a[i+n]=a[i]+len;
for (int i=1;i<=n;++i) b[i+n]=b[i],b[i]-=len;
for (int i=1;i<=n*2;++i) b[i+n*2]=b[i]+len*2;
int l=0,r=len>>1;
while (l<r){
int mid=(l+r)>>1;
if (check(mid)) r=mid;
else l=mid+1;
}
return !printf("%d",l);
}

洛谷 3488 [POI2009]LYZ-Ice Skates

题目

有 \(n\) 种尺码的鞋子,\(m\) 次操作,每种鞋子有 \(k\) 双,这 \(n\) 种尺码的队员分别有 \(a_i\) 个,初始为0。

对于一个尺码为 \(x\) 的队员可以穿的鞋子尺码范围为 \([x,x+d]\)

每次操作加入或者删除同一尺码的若干名队员,问在场的队员是否都能穿上鞋子。

\(n,m,d\leq 5*10^5,k\leq 10^9\)


分析

根据Hall定理,也就是任意队员的子集都能穿上鞋子,

考虑连续尺码一定比不连续尺码的差值 \((|X'|-|Y'|)\) 更大

\(\forall 1\leq l\leq r\leq n,\sum_{i=l}^r{a_i}\leq (r-l+1+d)*k\)

也就是 \(\sum_{i=l}^r(a_i-k)\leq k*d\)

那也就是最大子段和不超过 \(k*d\)

当 \(r+d>n\) 时,也就是当 \(r=n\) 时左边才可能最大,

那么 \(\sum_{i=l}^n{a_i}+l*k\leq (n+1)*k\)

维护前面这一坨的最大值即可


代码

#include <cstdio>
#include <cctype>
using namespace std;
const int N=500011; typedef long long lll; int n,m,d;
lll A,w[N<<2],s[N<<2],lazy[N<<2],_w[N<<2],lmx[N<<2],rmx[N<<2];
int iut(){
int ans=0,f=1; char c=getchar();
while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans*f;
}
void build(int k,int l,int r){
w[k]=s[k]=-(r-l+1)*A,_w[k]=r*A;
if (l==r) return;
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
}
lll max(lll a,lll b){return a>b?a:b;}
void update(int k,int l,int r,int x,int y){
if (l==r){
s[k]+=y,w[k]+=y;
if (s[k]>0) lmx[k]=rmx[k]=s[k];
else lmx[k]=rmx[k]=0;
return;
}
int mid=(l+r)>>1;
if (x<=mid) update(k<<1,l,mid,x,y);
else update(k<<1|1,mid+1,r,x,y);
rmx[k]=max(rmx[k<<1|1],s[k<<1|1]+rmx[k<<1]);
lmx[k]=max(lmx[k<<1],s[k<<1]+lmx[k<<1|1]),s[k]=s[k<<1]+s[k<<1|1];
w[k]=max(max(w[k<<1],w[k<<1|1]),rmx[k<<1]+lmx[k<<1|1]);
}
void upd(int k,int l,int r,int x,int y,int z){
if (l==x&&r==y) {_w[k]+=z,lazy[k]+=z; return;}
int mid=(l+r)>>1;
if (lazy[k]){
lazy[k<<1]+=lazy[k],lazy[k<<1|1]+=lazy[k];
_w[k<<1]+=lazy[k],_w[k<<1|1]+=lazy[k],lazy[k]=0;
}
if (y<=mid) upd(k<<1,l,mid,x,y,z);
else if (x>mid) upd(k<<1|1,mid+1,r,x,y,z);
else upd(k<<1,l,mid,x,mid,z),upd(k<<1|1,mid+1,r,mid+1,y,z);
_w[k]=max(_w[k<<1],_w[k<<1|1]);
}
int main(){
n=iut(),m=iut(),A=iut(),d=iut();
build(1,1,n);
for (int i=1;i<=m;++i){
int x=iut(),y=iut();
update(1,1,n,x,y),upd(1,1,n,1,x,y);
if (w[1]<=A*d&&_w[1]<=(n+1ll)*A) puts("TAK");
else puts("NIE");
}
return 0;
}

CF103E Buying Sets

题目

有一个大小为 \(n\) 的全集,每个元素是一个数,有 \(n\) 个子集。题目保证任意 \(k\) 个子集的并的大小 \(\geq k\)。(\(n\leq 300\))

每个子集有一个可正可负的权值,你需要选出一些子集使得这些子集并的大小等于子集个数,且所选子集的权值和最小。可以为空集。

LOJ 6045 「雅礼集训 2017 Day8」价

51nod 1551 集合交易


分析

如果将子集视为 \(X\),元素视为 \(Y\),那么 \(\forall X',|X'|\leq |Y'|\)

也就是说一定存在完美匹配,考虑将权值取反,改为求最大权值,用总和减去最大匹配即为答案(最小权闭合子图转化为最大权闭合子图),

构建一个最大权闭合子图模型,源点连子集,流量为 \(inf+x\),汇点连元素,流量为 \(inf\),中间子集和元素连接流量为 \(inf\)

由于中间的边断开肯定不优,所以只有可能断开源汇点连接的边,有了 \(inf\) 的流量也就是让左右两边的断边数量相等。

那么没有被断开的边就是最终选择的方案,同时子集并等于子集个数。


代码

#include <cstdio>
#include <cctype>
#include <queue>
using namespace std;
const int N=611,inf=1e9; typedef long long lll;
struct node{int y; lll w; int next;}e[N*N];
int as[N],dis[N],n,S,T,et=1; lll ans;
int iut(){
int ans=0,f=1; char c=getchar();
while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans*f;
}
void add(int x,int y,lll w){
e[++et]=(node){y,w,as[x]},as[x]=et;
e[++et]=(node){x,0,as[y]},as[y]=et;
}
bool bfs(int st){
for (int i=1;i<=T;++i) dis[i]=0;
queue<int>q; q.push(st),dis[st]=1;
while (!q.empty()){
int x=q.front(); q.pop();
for (int i=as[x];i;i=e[i].next)
if (e[i].w>0&&!dis[e[i].y]){
dis[e[i].y]=dis[x]+1;
if (e[i].y==T) return 1;
q.push(e[i].y);
}
}
return 0;
}
lll min(lll a,lll b){return a<b?a:b;}
lll dfs(int x,lll now){
if (x==T||!now) return now;
lll rest=0,f;
for (int i=as[x];i;i=e[i].next)
if (e[i].w>0&&dis[e[i].y]==dis[x]+1){
f=dfs(e[i].y,min(now-rest,e[i].w)),
rest+=f,e[i].w-=f,e[i^1].w+=f;
if (now==rest) return now;
}
if (!rest) dis[x]=0;
return rest;
}
int main(){
n=iut(),S=n<<1|1,T=S+1;
for (int i=1;i<=n;++i)
for (int j=iut();j;--j)
add(i,iut()+n,inf);
for (int i=1;i<=n;++i) add(i+n,T,inf);
for (int i=1;i<=n;++i){
int x=-iut();
add(S,i,inf+x),ans+=x;
}
while (bfs(S)) ans-=dfs(S,1e12);
ans+=1ll*n*inf;
return !printf("%lld",-ans);
}

[ARC106E] Medals

题目

\(n(n\leq 18)\) 个员工,从第一天开始,每人工作 \(a_i\) 天,休息 \(a_i\) 天,

每天任意挑选一个上班的人颁发奖状,问至少多少天所有人至少能拿到 \(m\) 块奖状。


分析

二分答案转为判定性问题,上界应该为 \(2*n*m\),就是最坏情况隔一天给一块

那么最直接的做法,就是员工和所在的时间连边跑最大流答案是否为 \(n*m\)

根据Hall定理,只需要判断任意员工的子集的邻域不小于子集大小即可。

预处理出每天哪些员工在场,然后用子集卷积求出每个子集的邻域大小再判断即可。


代码

#include <cstdio>
#include <cctype>
using namespace std;
const int N=300011;
int f[N],ban[N*12],xo[N],a[21],n,m,al,L;
int iut(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
bool check(int mid){
for (int i=0;i<al;++i) f[i]=0; f[al]=mid;
for (int i=1;i<=mid;++i) --f[ban[i]];
for (int j=0;j<n;++j)
for (int i=0;i<=al;++i)
if ((i>>j)&1) f[i^(1<<j)]+=f[i];
for (int i=0;i<=al;++i)
if (f[i]<xo[i]*m) return 0;
return 1;
}
int main(){
n=iut(),m=iut(),al=(1<<n)-1,L=n*m*2;
for (int i=1;i<=al;++i) xo[i]=xo[i&(i-1)]+1;
for (int i=0;i<n;++i) a[i]=iut();
for (int i=1,now=0;i<=L;++i){
ban[i]=now;
for (int j=0;j<n;++j)
if (i%a[j]==0) now^=1<<j;
}
int l=1,r=L;
while (l<r){
int mid=(l+r)>>1;
if (check(mid)) r=mid;
else l=mid+1;
}
return !printf("%d",l);
}

AT4505 [AGC029F] Construction of a tree

题目

有 \(n-1\) 个集合,现在要在每个集合中各选两个点连边,

问是否能连成一棵树,如果可以,输出一组方案。\(n\leq 10^5\)


分析

设 \(X\) 表示集合,\(Y\) 表示点,那么成为一棵树当且仅当 \(\forall X',|X'|<|Y'|\)

但是Hall定理只能处理小于等于的情况,那么先集合连点跑二分图匹配(实测匈牙利算法会T掉一个点)

然后记录每个集合选了哪个点,如果最大匹配不为 \(n-1\) 就一定无解。

否则那么一定有一个点剩下来,那么用这个点输出方案。

具体就是设当前点为 \(x\),找到未被使用的集合若其在二分图匹配时对应 \(y\),那么用 \(x\) 和 \(y\) 连边,并且继续搜索 \(y\)。

如果找不到合适的 \(y\) 同样无解。


代码

#include <cstdio>
#include <cctype>
#include <queue>
using namespace std;
const int N=200011; struct node{int y,w,next;}e[N<<2];
int v[N],link[N],as[N],X[N],Y[N],et=1,S,T,n,ans,rt,dis[N];
int iut(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
void add(int x,int y,int w){
e[++et]=(node){y,w,as[x]},as[x]=et;
e[++et]=(node){x,0,as[y]},as[y]=et;
}
bool bfs(int st){
for (int i=1;i<=T;++i) dis[i]=0;
queue<int>q; q.push(st),dis[st]=1;
while (!q.empty()){
int x=q.front(); q.pop();
for (int i=as[x];i;i=e[i].next)
if (e[i].w>0&&!dis[e[i].y]){
dis[e[i].y]=dis[x]+1;
if (e[i].y==T) return 1;
q.push(e[i].y);
}
}
return 0;
}
int min(int a,int b){return a<b?a:b;}
int dfs(int x,int now){
if (x==T||!now) return now;
int rest=0,f;
for (int i=as[x];i;i=e[i].next)
if (e[i].w>0&&dis[e[i].y]==dis[x]+1){
f=dfs(e[i].y,min(now-rest,e[i].w)),
rest+=f,e[i].w-=f,e[i^1].w+=f;
if (now==rest) return now;
}
if (!rest) dis[x]=0;
return rest;
}
void Dfs(int x){
for (int i=as[x];i;i=e[i].next)
if (!v[e[i].y]&&e[i].y!=S){
X[e[i].y]=x,Y[e[i].y]=link[e[i].y];
v[e[i].y]=1,--ans,Dfs(link[e[i].y]);
}
}
int main(){
n=iut(),S=n<<1,T=S+1;
for (int i=0;i<n;++i) add(S,i+n,1);
for (int i=1;i<n;++i) add(i,T,1);
for (int i=1;i<n;++i)
for (int j=iut();j;--j)
add(iut()+n-1,i,1);
while (bfs(S)) ans+=dfs(S,1e9);
for (int i=4*n;i<=et;i+=2)
if (!e[i].w) link[e[i].y]=e[i^1].y;
if (ans<n-1) return !printf("-1");
for (int i=1;i<=T;++i) v[i]=0;
for (int i=1;i<n;++i) v[link[i]]=1;
for (int i=n;i<2*n;++i) if (!v[i]) rt=i;
Dfs(rt);
if (ans) return !printf("-1");
for (int i=1;i<n;++i){
print(X[i]-n+1),putchar(32);
print(Y[i]-n+1),putchar(10);
}
return 0;
}

Hall定理小记的更多相关文章

  1. Hall定理 二分图完美匹配

    充分性证明就先咕了,因为楼主太弱了,有一部分没看懂 霍尔定理内容 二分图G中的两部分顶点组成的集合分别为X, Y(假设有\(\lvert X \rvert \leq \lvert Y \rvert\) ...

  2. 【CF981F】Round Marriage(二分答案,二分图匹配,Hall定理)

    [CF981F]Round Marriage(二分答案,二分图匹配,Hall定理) 题面 CF 洛谷 题解 很明显需要二分. 二分之后考虑如果判定是否存在完备匹配,考虑\(Hall\)定理. 那么如果 ...

  3. bzoj3693: 圆桌会议 二分图 hall定理

    目录 题目链接 题解 代码 题目链接 bzoj3693: 圆桌会议 题解 对与每个人构建二分,问题化为时候有一个匹配取了所有的人 Hall定理--对于任意的二分图G,G的两个部分为X={x1,x2,- ...

  4. TCO 2015 1A Hard.Revmatching(Hall定理)

    \(Description\) 给定一个\(n\)个点的二分图,每条边有边权.求一个边权最小的边集,使得删除该边集后不存在完备匹配. \(n\leq20\). \(Solution\) 设点集为\(S ...

  5. BZOJ.3693.圆桌会议(Hall定理 线段树)

    题目链接 先考虑链.题目相当于求是否存在完备匹配.那么由Hall定理,对于任意一个区间[L,R],都要满足[li,ri]完全在[L,R]中的ai之和sum小于等于总位置数,即R-L+1.(其实用不到H ...

  6. BZOJ.5404.party(树链剖分 bitset Hall定理)

    题目链接 只有指向父节点的单向道路,所以c个人肯定在LCA处汇合.那么就成了有c条到LCA的路径,求最大的x,满足能从c条路径中各选出x个数,且它们不同. 先要维护一条路径的数的种类数,可以树剖+每条 ...

  7. LOJ.6062.[2017山东一轮集训]Pair(Hall定理 线段树)

    题目链接 首先Bi之间的大小关系没用,先对它排序,假设从小到大排 那么每个Ai所能匹配的Bi就是一个B[]的后缀 把一个B[]后缀的匹配看做一条边的覆盖,设Xi为Bi被覆盖的次数 容易想到 对于每个i ...

  8. loj#6062. 「2017 山东一轮集训 Day2」Pair hall定理+线段树

    题意:给出一个长度为 n的数列 a和一个长度为 m 的数列 b,求 a有多少个长度为 m的连续子数列能与 b匹配.两个数列可以匹配,当且仅当存在一种方案,使两个数列中的数可以两两配对,两个数可以配对当 ...

  9. 【BZOJ2138】stone Hall定理+线段树

    [BZOJ2138]stone Description 话说Nan在海边等人,预计还要等上M分钟.为了打发时间,他玩起了石子.Nan搬来了N堆石子,编号为1到N,每堆包含Ai颗石子.每1分钟,Nan会 ...

  10. BZOJ1135:[POI2009]Lyz(线段树,Hall定理)

    Description 初始时滑冰俱乐部有1到n号的溜冰鞋各k双.已知x号脚的人可以穿x到x+d的溜冰鞋. 有m次操作,每次包含两个数ri,xi代表来了xi个ri号脚的人.xi为负,则代表走了这么多人 ...

随机推荐

  1. String--cannot convert from 'const char *' to 'LPTSTR'错误

    这种错误,很多情况下是类型不匹配 LPTSTR表示为指向常量TCHAR字符串的长指针 TCHAR可以是wchar_t或char,基于项目是多字节还是宽字节版本. 看下面的代码,代码来源:Example ...

  2. Redis原理再学习02:数据结构-动态字符串sds

    Redis原理再学习:动态字符串sds 字符 字符就是英文里的一个一个英文字母,比如:a.中文里的单个汉字,比如:好. 字符串就是多个字母或多个汉字组成,比如字符串:redis,中文字符串:你好吗. ...

  3. npm代理 -- 解决在公司内网如何装包的问题

    什么是Npm代理 npm代理指的是npm包管理器在使用时通过代理访问npm服务器获取依赖包的过程.在某些情况下,我们需要npm走代理才能访问到npm服务器,否则会出现timeout的错误.那下面我们就 ...

  4. RK3588开发笔记(二):基于方案商提供sdk搭建引入mpp和sdk的宿主机交叉编译Qt5.12.10环境

    前言   上一篇项目已经构建好了Qt,板子接入mipi屏幕也跑起来了,Qt也能正常运行了,现在需要接入定制开发的sdk,sdk中使用了硬解码等资源涉及到bsp的mpp,所以下一步就是引入mpp和sdk ...

  5. 学Python只需一张图

    有编程基础的人一看就可以了解 Python 的用法了.真正的 30 分钟上手.

  6. 【Azure Redis 缓存】对于Azure Redis 从 Redis 4 升级到 Redis 6 的一些疑问

    问题描述 使用Azure Redis服务,客户端使用Redisson 3.X , 在近期Microsoft Azure对Redis服务进行大规模变动升级( Redis 版本由 4 升级到 6),对于这 ...

  7. 【Azure 应用服务】App Service 使用Tomcat运行Java应用,如何设置前端网页缓存的相应参数呢(-Xms512m -Xmx1204m)?

    问题描述 App Service 使用Tomcat运行Java应用,如何设置前端网页缓存的相应参数呢(-Xms512m -Xmx1204m)? 问题回答 App Service在Windows的环境中 ...

  8. 使用rpa打开浏览器并执行js抓取页面元素详情步骤

    这里我们专门开一个文章来写如何在rpa中执行js获取页面元素. 个人觉得,复杂点的需求用js会方便很多,所以后续的文章我都会重点使用js去获取页面元素. 好,正文开始,我们先看一下rpa为我们提供的自 ...

  9. STM32F103xC,xD,xE引脚定义

    STM32F103xC,xD,xE引脚定义 由于在使用STM32系列芯片过程中发现互联网没有整理好的引脚定义,因此自己整理一份,方便以后查阅. GPIOA Pin 重新上电时的功能 默认功能 重映射 ...

  10. Linux性能监控(二)-top

    top命令可以用来监控服务器CPU.内存的运行情况,是Linux一个经常使用到的命令. 基本用法 第一行 显示当前系统运行信息,系统当前时间是23:23:21,运行了315days,当前有2个用户登录 ...