• 2019牛客暑期多校训练营(第四场)题解


    传送门

    按做题的顺序写好了……

    (K)

    对于(0)的情况单独考虑,剩下的一定是后面两个或更多的(0)加上前面一堆是(3)的倍数的数,后面(0)的情况可以预处理一下,前面只要记一下模(3)分别余(0/1/2)的数各有多少个就可以了

    //quming
    #include<bits/stdc++.h>
    #define R register
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    typedef long long ll;
    const int N=5e5+5;
    char s[N];int Pre[N],suf[N],sum[N],g[N],las[3],n;ll res;
    int main(){
    	scanf("%s",s+1),n=strlen(s+1);
    	fp(i,1,n)Pre[i]=(s[i-1]=='0'?Pre[i-1]+1:0);
    	fd(i,n,1)suf[i]=(s[i+1]=='0'?suf[i+1]+1:0);
    	fp(i,1,n)if(s[i]=='0'&&s[i+1]!='0')res+=1ll*(Pre[i]+1)*(Pre[i]+2)>>1;
    	fp(i,1,n)sum[i]=(sum[i-1]+(s[i]-'0'))%3;
    	las[0]=1;
    	fp(i,1,n)g[i]=las[sum[i]],las[sum[i]]=g[i]+1;
    	for(R int i=1;i<=n;++i)if(s[i]!='0'&&suf[i]>=2)res+=1ll*g[i]*(suf[i]-1);
    	printf("%lld
    ",res);
    	return 0;
    }
    

    (J)

    跑分层最短路,记(dis[i][j])表示走了(i)条免费边,到达(j)的最短路长度,对于每一个(i),先把内部跑完再拓展到(i+1)的情况就好了

    //quming
    #include<bits/stdc++.h>
    #define R register
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    const int N=1005;
    struct eg{int v,nx,w;}e[N<<1];int head[N],tot;
    inline void add(R int u,R int v,R int w){e[++tot]={v,head[u],w},head[u]=tot;}
    int dis[N][N],vis[N][N],n,m,S,T,k;
    struct node{
    	int u,p,d;
    	inline node(){}
    	inline node(R int uu,R int pp,R int dd):u(uu),p(pp),d(dd){}
    	inline bool operator <(const node &b)const{return d==b.d?p>b.p:d>b.d;}
    };priority_queue<node>q;
    void spfa(){
    	memset(dis,0x3f,sizeof(dis));
    	dis[S][0]=0;q.push(node(S,0,0));
    	while(!q.empty()){
    		int u=q.top().u,p=q.top().p;q.pop();if(vis[u][p])continue;
    		vis[u][p]=1;
    		if(u==T&&p==k)return;
    		go(u){
    			if(cmin(dis[v][p],dis[u][p]+e[i].w))q.push(node(v,p,dis[v][p]));
    			if(p<k&&cmin(dis[v][p+1],dis[u][p]))q.push(node(v,p+1,dis[v][p]));
    		}
    	}
    }
    int main(){
    	scanf("%d%d%d%d%d",&n,&m,&S,&T,&k);
    	for(R int i=1,u,v,w;i<=m;++i)scanf("%d%d%d",&u,&v,&w),add(u,v,w),add(v,u,w);
    	spfa();
    	printf("%d
    ",dis[T][k]);
    	return 0;
    }
    

    (A)

    (zzq)说这题很简单,记(d)为最远的两点之间的距离,答案就是(d/2)上取整,证明显然

    然后我跟个傻逼一样打了个换根(dp)来算……

    //quming
    #include<bits/stdc++.h>
    #define R register
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    const int N=5e5+5,inf=0x3f3f3f3f;
    struct eg{int v,nx;}e[N<<1];int head[N],tot;
    inline void add(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
    int dis[N],fr[N],dd[N],vis[N],n,k,res=inf;
    inline int max(R int x,R int y){return x>y?x:y;}
    void dfs1(int u,int fa){
    	dis[u]=(vis[u]?0:-inf),dd[u]=-inf,fr[u]=u;
    	go(u)if(v!=fa){
    		dfs1(v,u);
    		if(dis[v]+1>dis[u])dd[u]=dis[u],dis[u]=dis[v]+1,fr[u]=v;
    		else cmax(dd[u],dis[u]+1);
    	}
    }
    void dfs2(int u,int fa,int las){
    	cmin(res,max(las,dis[u]));
    	go(u)if(v!=fa){
    		if(v==fr[u])dfs2(v,u,max(las,dd[u])+1);
    		else dfs2(v,u,max(las,dis[u])+1);
    	}
    }
    int main(){
    	scanf("%d%d",&n,&k);
    	for(R int i=1,u,v;i<n;++i)scanf("%d%d",&u,&v),add(u,v),add(v,u);
    	for(R int x,i=1;i<=k;++i)scanf("%d",&x),vis[x]=1;
    	dfs1(1,0);
    	dfs2(1,0,-inf);
    	if(!k)res=0;
    	printf("%d
    ",res);
    	return 0;
    }
    

    (D)

    我好像根本没看到那个“输出尽可能少的数”……

    对于每一个二进制位,模(3)之后肯定是余(1)(2),我们把所有有(1)的二进制位按模(3)(1)还是余(2)分成两类,记为(A)(B),那么一个合法的数必然是在(A)中取(3)的倍数个(1)或在(B)中取(3)的倍数个(1)或在(AB)中同时取相同个数的(1),搞一搞就可以了

    //quming
    #include<bits/stdc++.h>
    #define R register
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    typedef long long ll;
    char sr[1<<21],z[20];int C=-1,Z=0;
    inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
    void print(R ll x){
        if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
        while(z[++Z]=x%10+48,x/=10);
        while(sr[++C]=z[Z],--Z);sr[++C]=' ';
    }
    const int N=1e5+5;
    int st[2][N],top[2],T;ll q[N],t,n;
    int main(){
    	for(scanf("%d",&T);T;--T){
    		scanf("%lld",&n);t=top[0]=top[1]=0;
    		for(R int i=0;n>>i;++i)if(n>>i&1)st[i&1][top[i&1]]=i,++top[i&1];
    		if(top[0]&&top[1]){
    			R int k=max(top[0],top[1]);
    			for(R int i=0,j=0;k;--k,i=(i+1)%top[0],j=(j+1)%top[1])
    				q[++t]=(1ll<<st[0][i])|(1ll<<st[1][j]);
    		}else if(top[0])fp(i,2,top[0]-1)q[++t]=(1ll<<st[0][i])|(1ll<<st[0][1])|(1ll<<st[0][0]);
    		else fp(i,2,top[1]-1)q[++t]=(1ll<<st[1][i])|(1ll<<st[1][1])|(1ll<<st[1][0]);
    		print(t);
    		fp(i,1,t)print(q[i]);
    		sr[++C]='
    ';
    	}
    	return Ot(),0;
    } 
    

    (C)

    我们考虑递归处理,记当前区间为([l,r]),且(p)为区间最小值所在的位置,那么我们需要找到一个跨过(p)的区间且满足(sum_{l',r'})最大(或者最小,看(a_p)是大于(0)还是小于(0)),先直接把(b)做个前缀和之后可以转化为分别在([p,r])([l-1,p-1])的区间中求最大最小值,线段树就行了,做完之后继续递归([l,p-1])([p+1,r])就行了

    //quming
    #include<bits/stdc++.h>
    #define R register
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    typedef long long ll;
    char buf[1<<21],*p1=buf,*p2=buf;
    inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    int read(){
        R int res,f=1;R char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    const int N=3e6+5;const ll inf=4e18;
    ll sum[N],res=-4e18;int n,a[N],b[N];
    inline ll min(R ll x,R ll y){return x<y?x:y;}
    inline ll max(R ll x,R ll y){return x>y?x:y;}
    inline int MIN(R int x,R int y){return a[x]<a[y]?x:y;}
    struct node;typedef node* ptr;
    struct node{
    	ptr lc,rc;ll mns,mxs;int mn;
    	inline void upd(){mns=min(lc->mns,rc->mns),mxs=max(lc->mxs,rc->mxs),mn=MIN(lc->mn,rc->mn);}
    }e[N<<2],*pp=e,*rt;
    void build(ptr &p,int l,int r){
    	p=++pp;if(l==r)return p->mns=p->mxs=sum[r],p->mn=r,void();
    	int mid=(l+r)>>1;
    	build(p->lc,l,mid),build(p->rc,mid+1,r);
    	p->upd();
    }
    int mn;ll mxs,mns;
    void qmn(ptr p,int l,int r,int ql,int qr){
    	if(ql<=l&&qr>=r)return mn=MIN(mn,p->mn),void();
    	int mid=(l+r)>>1;
    	if(ql<=mid)qmn(p->lc,l,mid,ql,qr);
    	if(qr>mid)qmn(p->rc,mid+1,r,ql,qr);
    }
    void qmns(ptr p,int l,int r,int ql,int qr){
    	if(ql<=l&&qr>=r)return cmin(mns,p->mns),void();
    	int mid=(l+r)>>1;
    	if(ql<=mid)qmns(p->lc,l,mid,ql,qr);
    	if(qr>mid)qmns(p->rc,mid+1,r,ql,qr);
    }
    void qmxs(ptr p,int l,int r,int ql,int qr){
    	if(ql<=l&&qr>=r)return cmax(mxs,p->mxs),void();
    	int mid=(l+r)>>1;
    	if(ql<=mid)qmxs(p->lc,l,mid,ql,qr);
    	if(qr>mid)qmxs(p->rc,mid+1,r,ql,qr);
    }
    void solve(int l,int r){
    	if(l>r)return;if(l==r)return cmax(res,1ll*b[r]*a[r]),void();
    	mn=0,qmn(rt,1,n,l,r);int p=mn;
    	ll a=0,b=0,c=0,d=0;
    	mxs=-inf,qmxs(rt,1,n,p,r),a=mxs;
    	mns=inf,qmns(rt,1,n,p,r),b=mns;
    	if(p>1)mxs=-inf,qmxs(rt,1,n,max(l-1,1ll),p-1),c=mxs;
    	if(p>1)mns=inf,qmns(rt,1,n,max(l-1,1ll),p-1),d=mns;
    	cmax(res,(a-d)*::a[p]),cmax(res,(b-c)*::a[p]);
    	solve(l,p-1),solve(p+1,r);
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	n=read();a[0]=0x3f3f3f3f;
    	fp(i,1,n)a[i]=read();
    	fp(i,1,n)b[i]=read(),sum[i]=sum[i-1]+b[i];
    	build(rt,1,n);
    	solve(1,n);
    	printf("%lld
    ",res);
    	return 0;
    } 
    

    (I)

    我们先直接数出本质不同的子串个数,记为(res),这个可以直接在(SAM)上跑

    考虑会被重复计算的子串,必然是自己以及反串都出现过,那么我们对于反串建一个(SAM),并把原串在上面跑,求出“原串与反串的本质不同的公共子串个数”,记为(sum)

    这个(sum)里包含什么呢?每一个自己和反串都出现过的子串(T)会在这里面被计数两次,而回文串会在里面的计数一次,需要从答案里减掉的只有(T),而回文串是不用减掉的

    那么我们用回文自动机求出本质不同的回文串个数,记为(ret),答案就是(res-(sum-ret)/2)

    最尴尬的是我忘了(SAM)(PAM)怎么写只好去抄板子结果连自己写的是啥都不知道了……

    //quming
    #include<bits/stdc++.h>
    #define R register
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    typedef long long ll;
    const int N=7e5+5;
    char s[N];int l[N],ch[N][26],fa[N],cc[N],cnt=1,las=1,n;ll res,sum,ret;
    void ins(int c){
        int p=las,np=++cnt;las=np,l[np]=l[p]+1;
        for(;p&&!ch[p][c];p=fa[p])ch[p][c]=np;
        if(!p)fa[np]=1;
        else{
            int q=ch[p][c];
            if(l[q]==l[p]+1)fa[np]=q;
            else{
                int nq=++cnt;l[nq]=l[p]+1;
                memcpy(ch[nq],ch[q],sizeof(ch[q]));
                fa[nq]=fa[q],fa[q]=fa[np]=nq;
                for(;ch[p][c]==q;p=fa[p])ch[p][c]=nq;
            }
        }
    }
    void clr(){
    	memset(fa,0,sizeof(fa)),
    	memset(l,0,sizeof(l)),
    	memset(ch,0,sizeof(ch)),
    	las=cnt=1;
    }
    void solve(){
    	for(R int p=1,i=1,c,len=0;i<=n;++i){
    		c=s[i]-'a';
    		while(p&&!ch[p][c])p=fa[p],len=l[p];
    		++len,p=ch[p][c],cmax(cc[p],len);
    	}
    }
    int c[N],q[N];
    void calc(){
    	fp(i,1,cnt)++c[l[i]];
    	fp(i,1,cnt)c[i]+=c[i-1];
    	fd(i,cnt,1)q[c[l[i]]--]=i;
    	fd(i,cnt,1)cmax(cc[fa[q[i]]],cc[q[i]]);
    	fp(i,1,cnt)cmin(cc[i],l[i]);
    	fp(i,1,cnt)sum+=max(0,cc[i]-l[fa[i]]);
    }
    int len[N],fail[N],tot;
    inline int newnode(int x){
        //建立一个新节点,长度为x 
        len[++tot]=x;return tot;
    }
    inline int getfail(int x,int n){
        //跳fail指针知道找到后缀回文为止 
        while(s[n-len[x]-1]!=s[n]) x=fail[x];
        return x;
    }
    void QAQ(){
    	memset(ch,0,sizeof(ch));
    	int last,p,q;
        s[0]=-1,fail[0]=1,last=0;
        len[0]=0,len[1]=-1,tot=1;
        for(int i=1;s[i];++i){
            s[i]-='a';
            //找到可以回文的位置 
            p=getfail(last,i);
            if(!ch[p][s[i]]){
                //如果有了转移就不用建了,否则要新建 
                //前后都加上新字符,所以新回文串长度要加2 
                q=newnode(len[p]+2);
                //因为fail指向的得是原串的严格后缀,所以要从p的fail开始找起 
                fail[q]=ch[getfail(fail[p],i)][s[i]]; 
                //记录转移 
                ch[p][s[i]]=q;
            }
            last=ch[p][s[i]];
        }
    //    fp(i,2,tot)ret+=len[i]-len[fail[i]],printf("%d %d %d
    ",i,len[i],fail[i]);
    	ret=tot-1;
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	scanf("%s",s+1),n=strlen(s+1);
    	fp(i,1,n)ins(s[i]-'a');
    	fp(i,1,cnt)res+=l[i]-l[fa[i]];
    	clr();
    	reverse(s+1,s+1+n);
    	fp(i,1,n)ins(s[i]-'a');
    	reverse(s+1,s+1+n);
    	solve();
    	calc();
    	QAQ();
    	printf("%lld
    ",res-((sum-ret)>>1));
    	return 0;
    }
    

    (B)

    看一下线性基求交的总结

    线段树维护线性基的交就行了

    //quming
    #include<bits/stdc++.h>
    #define R register
    #define int unsigned int
    #define fp(i,a,b) for(R int i=(a),I=(b);i<=I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b);i>=I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    char buf[1<<21],*p1=buf,*p2=buf;
    inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    int read(){
        R int res,f=1;R char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    const int N=1e5+5;
    struct Base{
    	int a[32];
    	inline Base(){memset(a,0,sizeof(a));}
    	inline Base(const Base &b){memcpy(a,b.a,128);}
    	inline int& operator [](const int &x){return a[x];}
    	bool ins(int x,bool fl){
    		if(!x)return 0;
    //		printf("%d
    ",x);
    		fd(i,31,0)if(x>>i&1){
    //			printf("%d %d %d
    ",i,x,fl);
    			if(a[i]){
    				x^=a[i];
    				if(!x)return false;
    			}else{
    				if(fl)a[i]=x;
    				return true;
    			}
    		}
    	}
    };
    Base merge(Base a,Base b){
    	Base na(a),tmp(a),gl;
    	int cur,d;
    	fp(i,0,31)if(b[i]){
    		cur=0,d=b[i];
    		fd(j,i,0)if(d>>j&1){
    			if(tmp[j]){
    				d^=tmp[j],cur^=na[j];
    				if(d)continue;
    				gl[i]=cur;
    			}else tmp[j]=d,na[j]=cur;
    			break;
    		}
    	}
    	return gl;
    }
    struct node;typedef node* ptr;
    struct node{
    	ptr lc,rc;Base v;
    	inline void upd(){v=merge(lc->v,rc->v);}
    }e[N<<2],*pp=e,*rt;
    int val[N][35],sz[N],n,q;
    void build(ptr &p,int l,int r){
    	p=++pp;if(l==r){fp(i,1,sz[r])p->v.ins(val[r][i],1);return;}
    	int mid=(l+r)>>1;
    	build(p->lc,l,mid),build(p->rc,mid+1,r);
    	p->upd();
    }
    int ql,qr,x;
    bool query(ptr p,int l,int r){
    	if(ql<=l&&qr>=r)return !p->v.ins(x,0);
    	int mid=(l+r)>>1;
    	if(ql<=mid&&!query(p->lc,l,mid))return false;
    	if(qr>mid&&!query(p->rc,mid+1,r))return false;
    	return true;
    }
    signed main(){
    //	freopen("testdata.in","r",stdin);
    	n=read(),q=read();
    	fp(i,1,n){
    		sz[i]=read();
    		fp(j,1,sz[i])val[i][j]=read();
    	}
    	build(rt,1,n);
    	while(q--)ql=read(),qr=read(),x=read(),puts(query(rt,1,n)?"YES":"NO");
    	return 0;
    }
    

    (E)

    先容斥一下,对于(S),转化为计算最多只有(S)这几位为(1)的方案数

    每一个二进制位上模(3)的余数只有(1)或者(2),分别记为(A)类和(B)类,那么若(S)中有(p)(A)类和(q)(B)类,则答案只与(p,q)有关

    可以先预处理出(f_{i,j,0/1/2})表示有不超过(i)(A)类的(1),不超过(j)(B)类的(1),总共模(3)(0/1/2)的方案数,那么最多只有(S)这几位为(1)的方案数就可以直接算了

    然后容斥一下就行了

    //quming
    #include<bits/stdc++.h>
    #define R register
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    typedef long long ll;
    const int P=998244353;
    inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
    inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
    inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
    inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
    int ksm(R int x,R ll y){
    	R int res=1;
    	for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
    	return res;
    }
    const int N=35;
    int f[N][N][3],C[N][N],c[2],T,res,sum;ll n,x;
    void init(){
    	f[0][0][0]=1;
    	fp(i,1,30)fp(k,0,2)upd(f[i][0][k],add(f[i-1][0][k],f[i-1][0][(k+2)%3]));
    	fp(i,0,30)fp(j,1,30)fp(k,0,2)upd(f[i][j][k],add(f[i][j-1][k],f[i][j-1][(k+1)%3]));
    	C[0][0]=1;
    	fp(i,1,30){
    		C[i][0]=1;
    		fp(j,1,i)C[i][j]=add(C[i-1][j-1],C[i-1][j]);
    	}
    }
    int main(){
    	init();
    	for(scanf("%d",&T);T;--T){
    		scanf("%lld%lld",&n,&x),res=c[0]=c[1]=0;
    		for(R int i=0;x>>i;++i)if(x>>i&1)++c[i&1];
    		fp(i,0,c[0])fp(j,0,c[1]){
    			sum=1ll*C[c[0]][i]*C[c[1]][j]%P*ksm(f[i][j][0],n)%P;
    			upd(res,(c[0]+c[1]-i-j)&1?P-sum:sum);
    		}
    		printf("%d
    ",res);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Django01
    WEB框架介绍
    前端插件介绍
    JQuery
    DOM
    js
    css
    HTML
    图片懒加载
    js中style,currentStyle和getComputedStyle的区别
  • 原文地址:https://www.cnblogs.com/yuanquming/p/11256736.html
Copyright © 2020-2023  润新知