无聊了开一套省选题刷刷……u1s1 感觉三个题都不错,难度也挺有梯度,是一道标准的省选难度的题(话说 CSP 前你刷省选题干嘛/ts/ts)

小 C 珂海星

T1:P4495 [HAOI2018]奇怪的背包(基础数论)

一开始看错题了,以为是不可做题(

根据斐蜀定理,假设取出的体积集合为 \(S\),那么可以拼出 \(w\) 的充要条件是 \(\gcd_{x\in S}\gcd(x,P)\mid\gcd(w,P)\),不难发现 \(\gcd(x,P),\gcd(w,P)\) 肯定是 \(P\) 的约数,因此我们考虑给 \(P\) 的约数编号 \(1,2,3,\cdots,d(P)\)。然后我们设 \(f_i\) 表示 \(S\) 的 \(\gcd\) 是编号为 \(i\) 的约数的倍数的集合 \(S\) 的个数,\(g_i\) 表示 \(S\) 的 \(\gcd\) 恰好是编号为 \(i\) 的约数的集合 \(S\) 的个数。那么如果记 \(c_i\) 表示有多少个 \(\gcd(V_i,P)\) 是编号为 \(i\) 的约数的倍数,根据莫反那一套理论 \(f_i=2^{c_i}\),而 \(g_i\) 可以通过对 \(f_i\) 做狄利克雷差分求得,再一遍狄利克雷前缀和即可求出每个 \(\gcd\) 的答案。由于这题 \(d(P)\) 只有 \(10^3\),因此可以暴力 \(d^2(P)\) 狄利克雷前缀和/差分。时间复杂度 \(\mathcal O(\sqrt{P}+d^2(P)+(n+q)\log P)\)

const int MAXF=2000;
const int MAXN=1e6;
int n,qu,p,c[MAXF+5],b[MAXF+5],pw[MAXN+5],cs[MAXF+5],css[MAXF+5];
vector<int> fc;map<int,int> id;
int main(){
scanf("%d%d%d",&n,&qu,&p);
for(int i=1;i*i<=p;i++) if(p%i==0){
fc.pb(i);
if(p/i!=i) fc.pb(p/i);
} sort(fc.begin(),fc.end());
for(int i=0;i<fc.size();i++) id[fc[i]]=i;
for(int i=1,x;i<=n;i++) scanf("%d",&x),c[id[__gcd(x,p)]]++;
for(int i=0;i<fc.size();i++) for(int j=0;j<fc.size();j++)
if(fc[j]%fc[i]==0) b[i]+=c[j];
for(int i=(pw[0]=1);i<=n;i++) pw[i]=(pw[i-1]<<1)%MOD;
for(int i=0;i<fc.size();i++) cs[i]=pw[b[i]];
for(int i=(int)(fc.size())-1;~i;i--){
for(int j=i+1;j<fc.size();j++) if(fc[j]%fc[i]==0)
cs[i]=(cs[i]-cs[j]+MOD)%MOD;
}
for(int i=0;i<fc.size();i++) for(int j=0;j<=i;j++) if(fc[i]%fc[j]==0)
css[i]=(css[i]+cs[j])%MOD;
while(qu--){int w;scanf("%d",&w);printf("%d\n",css[id[__gcd(p,w)]]);}
return 0;
}

T2:P4494 [HAOI2018]反色游戏(圆方树)

大概是这题的一个子问题?

首先注意到这题的样例答案要么是 \(0\) 要么是 \(2\) 的整数次幂,考虑什么情况下为 \(0\) 什么情况下为 \(2\) 的幂。注意到在我们操作的过程中,每个连通块中 \(1\) 的奇偶性是不会变的,因此如果一个连通块中 \(1\) 的个数是奇数答案就是 \(0\)。否则我们考虑对于每个连通块任取一个生成树,那么有这样一个性质,如果非树边选/不选的状态确定了,那么整个连通块的状态就确定了,具体构造方法就是从叶子开始,如果叶子权值是 \(1\) 就选其与父亲的边,如果是 \(0\) 则不选。因此一个连通块的方案数就是 \(2^{n'-m'+1}\),其中 \(n',m'\) 分别为该连通块的点数和边数。把所有连通块的方案乘在一起可以得到 \(2^{n-m+c}\)。其中 \(n,m,c\) 分别为点数、边数、连通块个数。

考虑怎么求这个东西,点数、边数的求法都是容易的,比较难的是连通块个数,这里有两种方法:

  • 方法一:注意到删点很困难,因此考虑线段树分治将删点变成加边,这样可以并查集维护,复杂度 \(Tn\log^2n\),然后便获得了 70 分的好成绩……
  • 方法二:注意到此题与 P5227 连通图 不同的一点是,此题每次只删一个点,因此我们不妨从割点的角度思考,我们考虑建出原图的圆方树,那么根据圆方树的一个性质:对于一个连通图中的每个点,删掉这个点后图中所有连通块,就是圆方树上所有与这个点相邻的所有方点所在的连通块,这样即可计算出删掉一个点后会多出多少个连通块,也进而可以计算出有多少个连通块满足连通块中 \(1\) 的个数为奇数。时间复杂度 \(\mathcal O(\sum n+m)\),可以通过。

这道题竟码了我 170+ 行,主要我把之前写的线段树分治给注释掉了导致代码里一车注释(

const int MAXN=1e5;
int n,m;char str[MAXN+5];
//struct node{int l,r;vector<pii> e;} s[MAXN*4+5];
//int bad_cnt=0,mul=1;
//void build(int k,int l,int r){
// s[k].l=l;s[k].r=r;s[k].e.clear();if(l==r) return;
// int mid=l+r>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);
//}
//void ins(int k,int l,int r,pii v){
// if(l>r) return;
// if(l<=s[k].l&&s[k].r<=r) return s[k].e.pb(v),void();
// int mid=s[k].l+s[k].r>>1;
// if(r<=mid) ins(k<<1,l,r,v);else if(l>mid) ins(k<<1|1,l,r,v);
// else ins(k<<1,l,mid,v),ins(k<<1|1,mid+1,r,v);
//}
//int f[MAXN+5],dep[MAXN+5],sum[MAXN+5];stack<pair<pii,int> > stk;
//int find(int x){return (!f[x])?x:find(f[x]);}
//void merge(int x,int y){
// x=find(x);y=find(y);if(x==y) return mul=2ll*mul%MOD,void();
// if(dep[x]<dep[y]) swap(x,y);stk.push(mp(mp(x,y),(dep[x]==dep[y])));
// f[y]=x;dep[x]+=(dep[x]==dep[y]);
// bad_cnt-=(sum[x]&1);bad_cnt-=(sum[y]&1);
// sum[x]+=sum[y];bad_cnt+=(sum[x]&1);
//}
//void undo(){
// pair<pii,int> p=stk.top();int x=p.fi.fi,y=p.fi.se,z=p.se;
// dep[x]-=z;sum[x]-=sum[y];f[y]=0;stk.pop();
//}
//int res[MAXN+5];
//void iterate(int k){
// int tmp=stk.size(),tmp_bad_cnt=bad_cnt,tmp_mul=mul;
// for(pii p:s[k].e) merge(p.fi,p.se);
// if(s[k].l==s[k].r){
// if(s[k].l>0) bad_cnt-=(str[s[k].l]=='1');
// res[s[k].l]=(bad_cnt)?0:mul;
// if(s[k].l>0) bad_cnt+=(str[s[k].l]=='1');
// } else iterate(k<<1),iterate(k<<1|1);
// while(stk.size()>tmp) undo();
// bad_cnt=tmp_bad_cnt;mul=tmp_mul;
//}
int deg[MAXN+5],pw[MAXN*2+5];
link_list<int,MAXN,MAXN*2> g;
link_list<int,MAXN*2,MAXN*4> t;
int stk[MAXN*2+5],dfn[MAXN+5],tp=0,low[MAXN+5];
int tim=0,ncnt,degt[MAXN*2+5];
void tarjan(int x){
dfn[x]=low[x]=++tim;stk[++tp]=x;
for(int e=g.hd[x];e;e=g.nxt[e]){
int y=g.val[e];
if(!dfn[y]){
tarjan(y);chkmin(low[x],low[y]);
if(low[y]>=dfn[x]){
++ncnt;int o;do {
o=stk[tp--];degt[o]++;
t.ins(ncnt,o);t.ins(o,ncnt);
// printf("%d %d\n",ncnt,o);
} while(o^y);//printf("%d %d\n",ncnt,x);
t.ins(ncnt,x);t.ins(x,ncnt);degt[x]++;
}
} else chkmin(low[x],dfn[y]);
}
}
int rt[MAXN*2+5],siz[MAXN*2+5],fa[MAXN*2+5],cntb[MAXN*2+5];
void dfs(int x,int f,int r){
rt[x]=r;siz[x]=1;fa[x]=f;cntb[x]=(x<=n)?(str[x]=='1'):0;
for(int e=t.hd[x];e;e=t.nxt[e]){
int y=t.val[e];if(y==f) continue;dfs(y,x,r);
siz[x]+=siz[y];cntb[x]+=cntb[y];
}
}
void clear(){
memset(deg,0,sizeof(deg));g.clear();t.clear();
memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));
tim=0;memset(degt,0,sizeof(degt));tp=0;
memset(rt,0,sizeof(rt));memset(siz,0,sizeof(siz));
memset(fa,0,sizeof(fa));memset(cntb,0,sizeof(cntb));
}
void solve(){
scanf("%d%d",&n,&m);
// build(1,0,n);
// for(int i=1,u,v;i<=m;i++){
// scanf("%d%d",&u,&v);if(u>v) swap(u,v);
// ins(1,0,u-1,mp(u,v));ins(1,u+1,v-1,mp(u,v));
// ins(1,v+1,n,mp(u,v));
// } scanf("%s",str+1);bad_cnt=0;mul=1;
// for(int i=1;i<=n;i++) bad_cnt+=(str[i]=='1'),sum[i]=(str[i]-'0');
// iterate(1);
// for(int i=0;i<=n;i++) printf("%d%c",res[i]," \n"[i==n]);
clear();ncnt=n;
for(int i=1,u,v;i<=m;i++){
scanf("%d%d",&u,&v);g.ins(u,v);g.ins(v,u);
deg[u]++;deg[v]++;
} scanf("%s",str+1);vector<int> roots;int c=0,sum_bad=0;
for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i),roots.pb(i),++c;
for(int r:roots) dfs(r,0,r),sum_bad+=(cntb[r]&1);
// for(int i=1;i<=ncnt;i++) printf("%d\n",cntb[i]);
printf("%d",(sum_bad)?0:pw[m-n+c]);
for(int i=1;i<=n;i++){
int _m=m-deg[i],_n=n-1,_c=c-1+degt[i],_sum_bad=sum_bad;
if(cntb[rt[i]]&1) _sum_bad--;
for(int e=t.hd[i];e;e=t.nxt[e]){
int y=t.val[e];
if(y==fa[i]) _sum_bad+=((cntb[rt[i]]-cntb[i])&1);
else _sum_bad+=((cntb[y])&1);
} printf(" %d",(_sum_bad)?0:pw[_m-_n+_c]);
} printf("\n");
}
int main(){
// freopen("game.in","r",stdin);freopen("game.out","w",stdout);
for(int i=(pw[0]=1);i<=MAXN*2;i++) pw[i]=(pw[i-1]<<1)%MOD;
int qu;scanf("%d",&qu);while(qu--) solve();
return 0;
}
/*
1
5 5
1 2
2 3
3 4
2 4
3 5
00000
*/

T3:P4493 [HAOI2018]字串覆盖(SAM+数据分治)

首先有一个显然的性质是我们肯定会每次选出 \(P\) 在 \(S\) 中左端点 \(\ge s\) 且最靠左的出现位置,然后将这些位置全部设为访问过并且贪心地向后取,直到后面不存在合法的位置或者 \(P\) 下一次出现位置的右端点 \(\le t\)。

考虑优化这个过程,注意到此题有一个奇奇怪怪的限制:\(51\le r−l\le 2000\) 的询问不超过 \(11000\) 个且随机生成。因此考虑数据分治,具体来说对于 \(r-l>2000\),我们建出两串的 SAM 然后线段树合并维护每个字符串在 endpos,那么每次询问我们找到 \(T[l...r]\) 在 SAM 上对应的节点 \(x\),然后每次在 \(x\) 的 edp 中二分找出结尾位置 \(>\) 上一个串的结尾位置 \(-l+r\) 且结尾位置最靠前的字符串,如果超过了 \(r\) 或者不存在则 break,否则答案加一,不难注意到这样最多跳 \(\dfrac{n}{2000}\) 次,复杂度 \(q·\dfrac{n}{2000}·\log n\)。对于 \(r-l\le 50\),注意到每次都暴力向后跳 edp 复杂度过高不能接受,而可能的情况并不是很多(只有 \(50\) 个可能的长度),对于这样的模型我们考虑倍增,具体来说我们将询问离线下来,然后枚举长度 \(len\),记 \(nxt_{i,j}\) 表示对于 \(S\) 中以 \(i\) 结尾长度为 \(len\) 的字符串,从 \(i\) 开始取(当作第 \(0\) 次取的位置)向后取到的第 \(2^j\) 个子串的结束位置是什么(如果不存在则 \(nxt_{i,j}=n+1\)),\(nxt_{i,0}\) 可以通过 \(r-l>2000\) 的倍增求出,这部分复杂度 \(50n\log n\)。预处理出 \(nxt_{i,j}\) 之后即可通过倍增在 \(\log n\) 时间内回答每个询问。至于 \(51\le r−l\le 2000\)……由于题目中那个奇奇怪怪的条件,把这样的询问按照 \(r-l>2000\) 的方法处理也可通过。

然后就是实现的事情了,对于这种码农题硬着头皮码就完事了,如果你代码水平像我一样都比较那啥,可能会像我一样码个 200 行(

const int MAXN=1e5;
const int MAXP=4e5;
const int MAX_ND=MAXP<<6;
const int LOG_N=18;
const int B=50;
int n,K;char s[MAXN+5],t[MAXN+5];
link_list<int,MAXP,MAXP> g;
namespace SAM{
int ch[MAXP+5][26],len[MAXP+5],lnk[MAXP+5],ncnt=1,cur=1;
int ed[MAXN*2+5];
void extend(char c,int ps){
int id=c-'a',nw=++ncnt,p=cur;
ed[ps]=nw;len[nw]=len[cur]+1;cur=nw;
while(p&&!ch[p][id]) ch[p][id]=nw,p=lnk[p];
if(!p) return lnk[nw]=1,void();
int q=ch[p][id];
if(len[q]==len[p]+1) return lnk[nw]=q,void();
int cl=++ncnt;len[cl]=len[p]+1;
lnk[cl]=lnk[q];lnk[q]=lnk[nw]=cl;
for(int i=0;i<26;i++) ch[cl][i]=ch[q][i];
while(p&&ch[p][id]==q) ch[p][id]=cl,p=lnk[p];
}
void build(){
for(int i=2;i<=ncnt;i++) g.ins(lnk[i],i);
}
}
int rt[MAXP+5];
namespace segtree{
struct node{int ch[2],fst,lst;} s[MAX_ND+5];
void pushup(int k){
s[k].fst=(s[k].ch[0])?s[s[k].ch[0]].fst:s[s[k].ch[1]].fst;
s[k].lst=(s[k].ch[1])?s[s[k].ch[1]].lst:s[s[k].ch[0]].lst;
}
int ncnt=0;
void insert(int &k,int l,int r,int p){
if(!k) k=++ncnt;
if(l==r) return s[k].fst=s[k].lst=p,void();
int mid=l+r>>1;
if(p<=mid) insert(s[k].ch[0],l,mid,p);
else insert(s[k].ch[1],mid+1,r,p);
pushup(k);
}
int merge(int x,int y,int l,int r){
if(!x||!y) return x+y;int z=++ncnt;
if(l==r) return s[z].fst=s[z].lst=l,z;
int mid=l+r>>1;
s[z].ch[0]=merge(s[x].ch[0],s[y].ch[0],l,mid);
s[z].ch[1]=merge(s[x].ch[1],s[y].ch[1],mid+1,r);
return pushup(z),z;
}
int findgeq(int k,int l,int r,int p){
// printf("walk %d %d %d %d\n",k,l,r,p);
if(p>s[k].lst||l>r) return n+1;
if(l==r) return l;
int mid=l+r>>1;
if(!s[k].ch[1]) return findgeq(s[k].ch[0],l,mid,p);
if(!s[k].ch[0]) return findgeq(s[k].ch[1],mid+1,r,p);
if(s[s[k].ch[0]].lst>=p) return findgeq(s[k].ch[0],l,mid,p);
else return findgeq(s[k].ch[1],mid+1,r,p);
}
}
int fa[MAXP+5][LOG_N+2];
void dfs(int x,int f){
fa[x][0]=f;//printf("dfs %d %d\n",x,f);
for(int e=g.hd[x];e;e=g.nxt[e]){
int y=g.val[e];dfs(y,x);
rt[x]=segtree::merge(rt[x],rt[y],1,n);
}
}
int getnxt(int p,int pos){
if(pos>n) return n+1;
return segtree::findgeq(rt[p],1,n,pos+1);
}
int getnode(int l,int r){
int cur=SAM::ed[r];
for(int i=LOG_N;~i;i--) if(SAM::len[fa[cur][i]]>=r-l+1) cur=fa[cur][i];
return cur;
}
ll ans[MAXN+5];
vector<pair<pii,int> > qv[B+5];
int nxt[MAXN+5][LOG_N+2];
ll sum[MAXN+5][LOG_N+2];
int main(){
// freopen("cover.in","r",stdin);freopen("cover.out","w",stdout);
scanf("%d%d%s%s",&n,&K,s+1,t+1);
for(int i=1;i<=n;i++) SAM::extend(s[i],i);SAM::cur=1;
for(int i=1;i<=n;i++) SAM::extend(t[i],i+n);
SAM::build();
for(int i=1;i<=n;i++) segtree::insert(rt[SAM::ed[i]],1,n,i);
dfs(1,0);
for(int i=1;i<=LOG_N;i++) for(int j=1;j<=SAM::ncnt;j++) fa[j][i]=fa[fa[j][i-1]][i-1];
int qu;scanf("%d",&qu);
for(int i=1;i<=qu;i++){
int s,t,l,r;scanf("%d%d%d%d",&s,&t,&l,&r);
int cur=getnode(l+n,r+n);
if(r-l+1>B){
ll res=0;
int lim=s+(r-l)-1,len=r-l+1;
while(1){
int ps=getnxt(cur,lim);
// printf("%d\n",ps);
if(ps>t) break;res+=K-(ps-len+1);
lim=(ps+len-1);
} ans[i]=res;
} else {
int lim=s+(r-l)-1;
int nt=getnxt(cur,lim);
if(nt>t) ans[i]=0;
else qv[r-l+1].pb(mp(mp(nt,t),i));
}
}
for(int i=1;i<=B;i++){
memset(nxt,0,sizeof(nxt));
memset(sum,0,sizeof(sum));
// printf("dealing %d\n",i);
for(int j=i;j<=n;j++){
int nd=getnode(j-i+1,j);
nxt[j][0]=getnxt(nd,j+i-1);
if(nxt[j][0]!=n+1) sum[j][0]=K-(nxt[j][0]-i+1);
// printf("%d %d\n",j,nxt[j][0]);
} nxt[n+1][0]=n+1;
for(int j=1;j<=LOG_N;j++){
for(int k=i;k+(1<<j)-1<=n+1;k++){
nxt[k][j]=nxt[nxt[k][j-1]][j-1];
sum[k][j]=sum[k][j-1]+sum[nxt[k][j-1]][j-1];
}
}
for(pair<pii,int> p:qv[i]){
int pos=p.fi.fi,r=p.fi.se,id=p.se;
// printf("qry %d %d %d\n",pos,r,id);
ll res=K-(pos-i+1);
for(int j=LOG_N;~j;j--) if(nxt[pos][j]<=r&&nxt[pos][j]){
// printf("%d %lld\n",j,sum[pos][j]);
res+=sum[pos][j];pos=nxt[pos][j];
} ans[id]=res;
}
}
for(int i=1;i<=qu;i++) printf("%lld\n",ans[i]);
return 0;
}

HAOI 2018 Round 1 题解的更多相关文章

  1. Codeforces Round #556 题解

    Codeforces Round #556 题解 Div.2 A Stock Arbitraging 傻逼题 Div.2 B Tiling Challenge 傻逼题 Div.1 A Prefix S ...

  2. LibreOJ β Round #2 题解

    LibreOJ β Round #2 题解 模拟只会猜题意 题目: 给定一个长为 \(n\) 的序列,有 \(m\) 次询问,每次问所有长度大于 \(x\) 的区间的元素和的最大值. \(1 \leq ...

  3. Codeforces Round #569 题解

    Codeforces Round #569 题解 CF1179A Valeriy and Deque 有一个双端队列,每次取队首两个值,将较小值移动到队尾,较大值位置不变.多组询问求第\(m\)次操作 ...

  4. Codeforces Round #557 题解【更完了】

    Codeforces Round #557 题解 掉分快乐 CF1161A Hide and Seek Alice和Bob在玩捉♂迷♂藏,有\(n\)个格子,Bob会检查\(k\)次,第\(i\)次检 ...

  5. CFEducational Codeforces Round 66题解报告

    CFEducational Codeforces Round 66题解报告 感觉丧失了唯一一次能在CF上超过wqy的机会QAQ A 不管 B 不能直接累计乘法打\(tag\),要直接跳 C 考虑二分第 ...

  6. Google kickstart 2022 Round A题解

    Speed Typing 题意概述 给出两个字符串I和P,问能否通过删除P中若干个字符得到I?如果能的话,需要删除字符的个数是多少? 数据规模 \[1≤|I|,|P|≤10^5 \] 双指针 设置两个 ...

  7. [题解]Mail.Ru Cup 2018 Round 1 - D. Changing Array

    [题目] D. Changing Array [描述] 给n个整数a[1],...,a[n],满足0<=a[i]<=2^k-1.Vanya可以对这n个数中任一多个数进行操作,即将x变为x' ...

  8. [题解]Mail.Ru Cup 2018 Round 1 - C. Candies Distribution

    [题目] C. Candies Distribution [描述] n个小朋友排排坐吃糖糖,小朋友从左到右编号1到n.每个小朋友手上有一定数量的糖.对于第i个小朋友来说,编号比他小的小朋友中有li个小 ...

  9. [题解]Mail.Ru Cup 2018 Round 1 - B. Appending Mex

    [题目] B. Appending Mex [描述] Ildar定义了一种方法,可以由一个数组产生一个数.具体地,从这个数组中任选一个子集,不在这个子集中的最小的非负整数称为mex,就是由这个数组得到 ...

随机推荐

  1. vue.$nextTick实现原理

    源码: const callbacks = [] let pending = false function flushCallbacks () { pending = false const copi ...

  2. Java正则中"\\\\"表示普通反斜杠

    Java中"\"用于转义字符,"\\"表示普通无转义功能的反斜杠. 如果将字符串当做正则表达式来解析,那么"\\"也有了特殊意义,它与其后的 ...

  3. Redis:学习笔记-04

    Redis:学习笔记-04 该部分内容,参考了 bilibili 上讲解 Redis 中,观看数最多的课程 Redis最新超详细版教程通俗易懂,来自 UP主 遇见狂神说 10. Redis主从复制 1 ...

  4. AIApe问答机器人Scrum Meeting 5.1

    Scrum Meeting 5 日期:2021年5月1日 会议主要内容概述:汇报两日工作. 一.进度情况 组员 负责 两日内已完成的工作 后两日计划完成的工作 工作中遇到的困难 李明昕 后端 Task ...

  5. boost编译中的细节问题

    原文链接 http://www.cppblog.com/Robertxiao/archive/2013/01/06/197022.html 生成文件命名规则:boost中有许多库,有的库需要编译.而有 ...

  6. 零基础入门该如何实现C 语言面向对象编程(很有帮助)

    零基础如果更快更好的入门C语言,如何在枯燥的学习中找到属于自己的兴趣,如果把学习当成一种事务性的那以后的学习将会很难有更深入的进步,如果带着乐趣来完成学习那将越学越有意思这样才会让你有想要更深入学习的 ...

  7. 零基础学习Linux必会的60个常用命令

    Linux必学的60个命令Linux提供了大量的命令,利用它可以有效地完成大量的工 作,如磁盘操作.文件存取.目录操作.进程管理.文件权限设定等.所以,在Linux系统上工作离不开使用系统提供的命令. ...

  8. 单片机stm32零基础入门之--初识STM32 标准库

    CMSIS 标准及库层次关系 因为基于Cortex 系列芯片采用的内核都是相同的,区别主要为核外的片上外设的差异,这些差异却导致软件在同内核,不同外设的芯片上移植困难.为了解决不同的芯片厂商生产的Co ...

  9. Java代理:静态代理、JDK动态代理和CGLIB动态代理

    代理模式(英语:Proxy Pattern)是程序设计中的一种设计模式.所谓的代理者是指一个类别可以作为其它东西的接口.代理者可以作任何东西的接口:网络连接.存储器中的大对象.文件或其它昂贵或无法复制 ...

  10. Python展示文件下载进度条

    前言 大家在用Python写一些小程序的时候,经常都会用到文件下载,对于一些较小的文件,大家可能不太在乎文件的下载进度,因为一会就下载完毕了. 但是当文件较大,比如下载chromedriver的时候, ...