【题解】P8338 [AHOI2022] 排列

一道好的思维题!

题目链接

[AHOI2022] 排列 - 洛谷

题意概述

对于一个长度为 \(n\) 的排列 \(P = (p_1, p_2, \ldots, p_n)\) 和整数 \(k \ge 0\),定义 \(P\) 的 \(k\) 次幂

\[P^{(k)} = \left( p^{(k)}_1, p^{(k)}_2, \ldots, p^{(k)}_n \right) \]

该排列的第 \(i\) 项为

\[p^{(k)}_i = \begin{cases} i, & k = 0, \\ p^{(k - 1)}_{p_i}, & k > 0. \end{cases} \]

容易证明任意排列的任意次幂都是一个排列。

定义排列 \(P\) 的循环值 \(v(P)\) 为最小的正整数 \(k\) 使得 \(P^{(k + 1)} = P\)。

给出一个长度为 \(n\) 的排列 \(A = (a_1, a_2, \ldots, a_n)\),对于整数 \(1 \le i, j \le n\),定义 \(f(i, j)\):若存在 \(k \ge 0\) 使得 \(a^{(k)}_i = j\),则 \(f(i, j) = 0\),否则设排列 \(A_{i j}\) 为将排列 \(A\) 的第 \(i\) 项 \(a_i\) 和第 \(j\) 项 \(a_j\) 交换后得到的排列,则 \(f(i, j) = v(A_{i j})\)。

求 \(\sum_{i = 1}^{n} \sum_{j = 1}^{n} f(i, j)\) 的值。答案可能很大,你只需要输出其对 \(({10}^9 + 7)\) 取模的结果。

思路分析

首先我们可以考虑一个 OI 中比较常见的技巧——化数为图,在这道题里的具体体现就是,对于输入的 \(a_i\),我们连一条 \(i\) 到 \(a_i\) 的有向边。

那么其实可以发现,整张图是若干个环构成的。

根据题意我们可以知道,\({a_i}^{(k)}=j\) 其实就是相当于在图上从 \(i\) 出发走了 \(k\) 步走到了 \(j\)。


由于题目中要求的是 \(\sum \limits_{i=1}^n\sum \limits_{j=1}^n f(i,j)\) 那么我们为了求这个式子,可以先考虑把 \(f(i,j)\) 单独拿出来,看它怎么求。

根据题意可以分类讨论:

  • 当 \(i,j\) 在同一个环中时:

    说明 \(i\) 可以在图上到达 \(j\),即 \({a_i}^{(k)}=j\),此时 \(f(i,j)=0\);

    这里可以利用并查集直接判环。

  • 当 \(i,j\) 不在同一个环上时:

    根据题意,我们需要交换 \(i\) 和 \(j\) 并求出交换后的序列的循环值。


那么我们应该如何求出一个序列的循环值呢?

由于我们已经将这个序列转化为图,所以我们可以考虑直接在图上求解。

假如图上有 \(k\) 个环,大小分别是 \(sz_1,sz_2,sz_3,\cdots,sz_k\)。

根据循环值的定义,是序列经过变换之后回到原序列所用的步数。

对应在图上其实就是 \(\operatorname{lcm}(sz_1,sz_2,sz_3,\cdots,sz_k)\)。

这个很好理解,其实就相当于让每一个环都同时回到最初的起点所用的最短时间嘛。

那么我们就解决了在图上求序列循环值的问题。


现在我们在回过头来看刚刚要解决的问题,发现我们要求的是原图上交换 \(i\) 和 \(j\) 之后的循环值,而非原图循环值。

那么我们就要弄清楚:交换 \(i\) 和 \(j\) 之后,新图和原图发生了什么变化?

别急,我们先画个图看看!

假如这是原图,我们现在要交换 \(2\) 和 \(5\),那么实际上就是将原图中的 \(1 \to 2\) 和 \(5 \to 6\) 改成

\(1 \to 5\) 和 \(2 \to 6\),如下:

我们发现,以前的两个环合并成了一个环长为以前两个环之和的大环!

那么是不是所有的交换都满足这样的规律呢?

实际上是的,证明如下:

假设 \(i\) 的前驱是 \(pre_i\),后继是 \(nxt_i\),原来的两个环是 \(pre_i\to i \to nxt_i \to \cdots \to pre_i\) 和 \(pre_j \to j \to nxt_j \to \cdots pre_i\),那么交换 \(i\) 和 \(j\) 之后,相当于把 \(i \to nxt_i\) 和 \(j \to nxt_j\) 变成了 \(i \to nxt_j\) 和 \(j \to nxt_i\) 那么变换之后的新环是 \(pre_i\to i \to nxt_j \to \cdots \to pre_j \to j \to nxt_i \to \cdots pre_i\)。


那么我们直接在变换后的新环上求新的循环值即可。

我们现在已经知道了如何求单个 \(f(i,j)\),那么如何求出整个 \(\sum \limits_{i=1}^n \sum \limits_{j=1}^n f(i,j)\) 呢。

如果直接暴力,总复杂度是 \(O(n^3 \log n)\) 的,期望得分 40 分。

考虑优化。

首先考虑,两个 \(f(i,j)\) 在什么情况下相同。

不难看出,对于两个 \(f(a,b)\) 和 \(f(x,y)\),当 \(a\) 和 \(x\) 处在同一个环上,且 \(x\) 和 \(y\) 处在同一个环上时,\(f(a,b)=f(x,y)\)。

那么我们可以直接对于环考虑,假设图中一共有 \(k\) 个环,答案就可以转化为 \(\sum \limits_{i=1}^k \sum \limits_{j=1}^k f(i,j)\) (其中 \(i,j\) 表示的都是具体的哪个环)。


但是这样做在最坏情况下还可能会退化成 \(n^2\) 级别的复杂度。

这时候就要用到一个常见的技巧:

若存在 \(\sum a_i=n\),则本质不同的 \(a_i\) 最多有 \(\sqrt{n}\) 种。

证明很简单,当 \(\sum a_i=n\) 时,如果把序列 \(A\) 按照从小到大排序,最坏情况下 \(a_1=1,a_2=2,a_3=3,\cdots\) 这种情况下 \(a_n\) 最大是 \(\sqrt{n}\) 级别的。

那么我们只需要枚举本质不同的环长,假设本质不同的环长有 \(m\) 个,问题就转化为 \(\sum \limits_{i=1}^m \sum \limits_{j=1}^m f(i,j)\)(其中 \(i,j\) 表示本质不同的环长)。

此时枚举的复杂度由 \(n^2\) 变成了线性。

设 \(w(i,j)\) 表示合并了环长 \(i\) 和环长 \(j\) 之后排列的循环值,我们考虑它对答案产生了多少贡献。

设 \(cnt_i\) 表示整张图中有多少个环长为 \(i\) 的环,分类讨论:

  • 当 \(i=j\) 时:

    首先要满足 \(cnt_i \ge 2\),只有大于等于 \(2\) 个环才能交换。根据乘法原理,此时对答案的贡献是:\(i\times cnt_i \times i \times (cnt_i-1)\)。

  • 当 \(i \ne j\) 时:

    对答案产生的贡献为:\(i\times cnt_i \times j \times cnt_j\)。

然后我们暴力枚举 \(i,j\) 求解 \(w(i,j)\),一个优化常数的小技巧是,枚举一个 \(i\) 时,可以直接从 \(j+1\) 开始枚举,最后结果乘 \(2\) 即可。

此时,时间复杂度为 \(O(n\times m \log n)=O(n\sqrt n \log n)\)。期望得分 80 分。


梳理一下目前的思路会发现,现在时间复杂度的瓶颈就在于我们每次求 \(w(i,j)\) 的时候,要重新求一遍得到的新的图上所有环长的 \(\operatorname{lcm}\),非常麻烦。

那么如何优化呢?

思考一下便可以发现,我们这一步实际上要维护一个原来的 \(\operatorname{lcm}\) 删除其中两个数,增加一个新的数之后的新的 \(\operatorname{lcm}\) 的操作。

乍一看似乎很难维护,那么这时候我们就需要抛开问题的表面,然后去探求 \(\operatorname{lcm}\) 的本质。

我们知道,对于一个序列 \(a\) 中的一个元素 \(a_i\),假如它的因式分解形式是:

\[a_i={p_1}^{k_1}{p_2}^{k_2} {p_3}^{k_3} \cdots {p_q}^{k^q} \]

那么这个序列中所有的数的 \(\operatorname{lcm}\) 就为:

\[\operatorname{lcm}={p_1}^{\max(k_1)}{p_2}^{\max(k_2)}{p_3}^{\max(k_3)}\cdots {p_q}^{\max(k_q)} \]

这给我们一个启发:可以去考虑处理出来序列中所有数的因式分解形式,然后利用这个来维护 \(\operatorname{lcm}\)。

这里就用到一个常用的小技巧:

要处理出来 \(1-n\) 内的所有数的质因子,可以先用欧拉筛预处理出 \(1-n\) 范围内的所有数的最小质因子

然后对于每一个数 \(num\),我们先给它除以它本身的最小质因子 \(p1\),得到它除自身外的最大因子 \(pr1\),然后再除以 \(pr1\) 的最小质因子 \(p2\),得到 \(num\) 除自身外第二大因子 \(pr2\),以此类推……把处理出来的所有质因子都直接存到 \(num\) 的质因子集合中。

枚举 \(1-n\) 的每一个数,都这样做一遍就可以处理出来所有的质因子集合。

时间复杂度 \(O(n \log n)\)。

到这里,问题就转化成了:

已知一些数的质因子分解形式,然后要从中删掉两个数,增加一个数之后, 最后求得的 \(\operatorname{lcm}\)(所有剩下的数的最大质因子幂之积)是多少。

有一个比较易懂的做法就是:我们只需要维护原始集合下所有数中每个质因子最大的 \(3\) 个幂,因为你每次只会最多对三个数进行更改,后面的不会影响到新的 \(\operatorname{lcm}\)。

然后对于每次的操作,假如你要删掉的是 \(a\) 和 \(b\),增加的是 \(c\),那么你首先就在原先的质因子集合中,首先判断 \(a\) 和 \(b\) 对应的每一个质因子,是否在前三大幂的质因子集合中。如果在,则删掉;如果不在,则直接不用做任何操作。接着,再将对于 \(c\) 的每一个质因子,判断它对应的幂是否能加入到新的前三大幂的集合中,如果可以,则加入,如果不行,同样不进行任何操作。

这样暴力的加加减减之后,形成的新的质因子集合中的每个数的最大幂的积就是最后的本次询问的 \(\operatorname{lcm}\)。

注意:每次求完新的 \(\operatorname{lcm}\) 之后,还要把质因子集合还原为以前的质因子集合,因为每次操作都是对于最原始的那张图而言的。

总时间复杂度 \(O( n \log n)\)。期望得分 100 分。

最后这里的代码实现难度很大,所以我专门在这里放了一下这部分的代码:

#define int long long
#define mk make_pair
using namespace std;
const int maxn=5e5+10;
const int mod=1e9+7;
int a[maxn],fa[maxn];//a 表示输入序列,fa 表示并查集上每个点的祖先。
int vis[maxn],p[maxn];//vis 存储的是每个数的最小质因子,p 存储的是 5e5 内的质因子。
int pcnt[maxn];//pcnt 用来存储每个数有多少个质因子。
int sz[maxn],c[maxn];//sz 用来存储每一个环的大小,c 用来记录每一个环长有多少个。
int huan[maxn];//环长集合。
int inv[maxn],cntp[maxn];//计数器
int cnt,ans,lcm; vector<pair<int,int> >pri[maxn],g[maxn];
//pri 存储每个数的具体质因子(first)以及幂(second),g 是个临时动态数组,存储的是当前这个数被删/加了多少次。
vector<int>f[maxn];//f 表示的是每个质因子有哪些幂。
void insert(int x)//插入新加入的数的 lcm
{for(auto y:pri[x]){int p=y.first,q=y.second;f[p].push_back(q);sort(f[p].begin(),f[p].end(),cmp);if(f[p].size()>3)f[p].pop_back(); }return ;
}int get(int x)//得到新的最大幂。
{int ret=1;for(int y:f[x])cntp[y]++;for(auto y:g[x])cntp[y.first]+=y.second;for(int y:f[x]){if(cntp[y])ret=max(ret,y),cntp[y]=0;}for(auto y:g[x]){if(cntp[y.first])ret=max(ret,y.first),cntp[y.first]=0;}return ret;
}void upd(int x,int num)//更新 lcm
{for(auto y:pri[x]){int p=y.first,q=y.second;(lcm*=inv[get(p)])%=mod;g[p].push_back(mk(q,num));(lcm*=get(p))%=mod;}
}void clearg(int x)//最后做完之后要清零。
{for(auto y:pri[x])g[y.first].clear();
}
//主函数内
//初始化 lcm
lcm=1;
for(int i=1;i<=n;i++)
{if(f[i].empty())continue;(lcm*=f[i][0])%=mod;
}
//i=j 的情况。
for(int i=1;i<=cnt;i++)
{if(c[huan[i]]<=1)continue;int tt=lcm;upd(huan[i]+huan[i],1);upd(huan[i],-2);(ans+=lcm*huan[i]%mod*c[huan[i]]%mod*(c[huan[i]]-1)%mod*(huan[i])%mod)%=mod;clearg(huan[i]+huan[i]);lcm=tt;
}
//i!=j 的情况。
for(int i=1;i<=cnt;i++)
{for(int j=i+1;j<=cnt;j++){int tt=lcm;upd(huan[i]+huan[j],1);upd(huan[i],-1);upd(huan[j],-1);(ans+=2*lcm%mod*huan[i]%mod*c[huan[i]]%mod*c[huan[j]]%mod*huan[j]%mod)%=mod;clearg(huan[i]+huan[j]);clearg(huan[i]);clearg(huan[j]);lcm=tt;}
}

总的梳理一下,我们的思考过程大概就是:

化数为图 \(\to\) 转化为所有环的 \(\operatorname{lcm}\) \(\to\) 发现交换两个数之后会把两个小的环合并为一个新的大环 \(\to\) 发现本质不同的环长最多只有 \(\sqrt n\) 种 \(\to\) 刨开 \(\operatorname{lcm}\) 的本质利用质因子分解的办法优化求 \(\operatorname{lcm}\) 的过程。

实现步骤

  1. 预处理出来 \(1-n\) 以内所有的质因子集合。

  2. 读入,并利用并查集化数为图;

  3. 预处理出来原 \(\operatorname{lcm}\);

  4. 处理出来初始的质因子最大的 \(3\) 个幂集合;

  5. 分类讨论,枚举环长,分别对于 \(i=j\) 和 \(i \ne j\) 分别求解并乘上对应贡献。

代码实现

//luoguP8338
//remake.
#include<cstdio>
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstring>
#define int long long
#define mk make_pair
using namespace std;
const int maxn=5e5+10;
const int mod=1e9+7;
int a[maxn],fa[maxn];//a 表示输入序列,fa 表示并查集上每个点的祖先。
int vis[maxn],p[maxn];//vis 存储的是每个数的最小质因子,p 存储的是 5e5 内的质因子。
int pcnt[maxn];//pcnt 用来存储每个数有多少个质因子。
int sz[maxn],c[maxn];//sz 用来存储每一个环的大小,c 用来记录每一个环长有多少个。
int huan[maxn];//环长集合。
int inv[maxn],cntp[maxn];//计数器
int cnt,ans,lcm; vector<pair<int,int> >pri[maxn],g[maxn];
//pri 存储每个数的具体质因子(first)以及幂(second),g 是个临时动态数组,存储的是当前这个数被删/加了多少次。
vector<int>f[maxn];//f 表示的是每个质因子有哪些幂。 inline int read()
{int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}return x*f;
}int cmp(int a,int b){return a>b;}void init()
{inv[0]=inv[1]=1;for(int i=2;i<=500000;i++)inv[i]=(mod-mod/i)*inv[mod%i]%mod;int cnt=0;for(int i=2;i<=500000;i++){if(!vis[i]){vis[i]=i;p[++cnt]=i;}for(int j=1;j<=cnt&&i*p[j]<=500000;j++){if(p[j]>vis[i])break;vis[i*p[j]]=p[j];}}for(int i=2;i<=500000;i++){int t=i;while(t>1){int now=vis[t];int val=1;while(!(t%now)){val*=now;t/=now;}pri[i].push_back(mk(now,val));}}
}int find(int x)
{if(x!=fa[x])fa[x]=find(fa[x]);return fa[x];
}void add(int x,int y)
{x=find(x);y=find(y);if(x==y)return ;if(sz[x]>sz[y])swap(x,y);//启发式合并。 fa[x]=y;sz[y]+=sz[x];
}void insert(int x)
{for(auto y:pri[x]){int p=y.first,q=y.second;f[p].push_back(q);sort(f[p].begin(),f[p].end(),cmp);if(f[p].size()>3)f[p].pop_back(); }return ;
}int get(int x)
{int ret=1;for(int y:f[x])cntp[y]++;for(auto y:g[x])cntp[y.first]+=y.second;for(int y:f[x]){if(cntp[y])ret=max(ret,y),cntp[y]=0;}for(auto y:g[x]){if(cntp[y.first])ret=max(ret,y.first),cntp[y.first]=0;}return ret;
}void upd(int x,int num)
{for(auto y:pri[x]){int p=y.first,q=y.second;(lcm*=inv[get(p)])%=mod;g[p].push_back(mk(q,num));(lcm*=get(p))%=mod;}
}void clearg(int x)
{for(auto y:pri[x])g[y.first].clear();
}signed main()
{
//    freopen("data.in","r",stdin);
//    freopen("data.out","w",stdout);init();//预处理 1-n 每个数的质因子。(nlogn 分解质因数) int T=read();while(T--){ans=0;int n;n=read();memset(c,0,sizeof(c));memset(huan,0,sizeof(huan));for(int i=1;i<=n;i++)f[i].clear();for(int i=1;i<=n;i++)fa[i]=i,sz[i]=1;//初始化 fa 数组。 for(int i=1;i<=n;i++){a[i]=read();add(i,a[i]);//每次将 i 与 a[i] 连边(合并) }
//        for(int i=1;i<=n;i++)
//        {
//            cout<<a[i]<<endl;
//            for(auto y:pri[a[i]])
//            {
//                cout<<y.second<<" ";
//            }
//            cout<<endl;
//        }cnt=0;//cnt 表示的是有多少种不同的环长。 for(int i=1;i<=n;i++){if(fa[i]==i)//如果它本身就是祖先。 {if(!c[sz[i]])//原先环长集合中没有这个数,则将其加入环长集合。 {huan[++cnt]=sz[i]; }c[sz[i]]++;insert(sz[i]);}} //初始化 lcmlcm=1; for(int i=1;i<=n;i++){if(f[i].empty())continue;(lcm*=f[i][0])%=mod;} //i=j 的情况。 for(int i=1;i<=cnt;i++){if(c[huan[i]]<=1)continue;int tt=lcm;upd(huan[i]+huan[i],1);upd(huan[i],-2);(ans+=lcm*huan[i]%mod*c[huan[i]]%mod*(c[huan[i]]-1)%mod*(huan[i])%mod)%=mod;clearg(huan[i]+huan[i]);lcm=tt;}for(int i=1;i<=cnt;i++){for(int j=i+1;j<=cnt;j++){int tt=lcm;upd(huan[i]+huan[j],1);upd(huan[i],-1);upd(huan[j],-1);(ans+=2*lcm%mod*huan[i]%mod*c[huan[i]]%mod*c[huan[j]]%mod*huan[j]%mod)%=mod;clearg(huan[i]+huan[j]);clearg(huan[i]);clearg(huan[j]);lcm=tt;}} cout<<ans<<endl;}
}
/*重新梳理一下写题思路:
- 首先,预处理出来 1-5e5 范围内所有的数的质因子,具体做法:- 先用欧拉筛跑一遍把 1-5e5 范围内的所有质因子预处理出来;- 再枚举 1-5e5,然后每次除以这个数的最小质因子然后处理出来这个数所有的质因子。
- 其次,处理每一组数据,对于每一组输入的数据,让 i 与 a[i] 连边,实际上只需要在并查集中直接将它们俩直接合并,并维护一下合并后的集合的大小,这里为了更加优雅也降低时限,可以采用启发式合并处理集合大小。
- 然后处理出来所有的环长。
- 然后枚举每一个环长,直接把每一次得到的答案并入总答案中,具体处理方法如下:- 假设每一个环长的答案是 tt。那么对于每一次枚举的环长 i 和 j:- 若 i=j:则答案累加 sz[i]*c[i]*(c[i]-1)*sz[i]*tt;- 若 i!=j:则答案累加 sz[i]*c[i]*sz[j]*c[j]*tt; - 现在考虑每一个 tt 如何求:首先要维护一个原来的所有环长的 lcm 集合,对于一个质因子 i 维护它的幂 j,可以用 pair 来实现。 并且只需要维护对于每一个质因子 i 而言它的前 3 大幂即可。 假设每次删除的是 i 和 j,那么每次从 lcm 集合中删除 i 和 j 一个 i 和 j 对应质因数的幂,如果这个幂不在质因子对应的前 3 大集合里面可以直接将它忽略。然后再插入一个 i+j,同理将 i+j 对应质因子的幂加入集合里。
*/

总结

这道题让我意识到了两点:

  • 自己码力有点太弱了,,这种复杂的题要写好久。

  • 我写了那么多题并不是没有用。因为这道题里面大多技巧都是我在其它各个地方见过的。

    同时也让我探索到了一些适合自己的学习方法:

    我并不是那种思维能力强的人,相反我可能是机房里面最笨的思维能力最差的人,但是我做了不少题目,见过很多套路和技巧,这使得我在赛场上不是完全无从下手。

    也就是说,我需要在赛场上把题目转化为我做过的某一个或者某几个题目,通过记忆和联想从而在做过的旧题中得到启发,从而做出新题。

    这也告诉我在剩下两个月的时间里,应该多见新题,多了解套路和技巧,而不要做太难太高深的题目,而应该回归基础算法,掌握更多,我原本就该掌握的东西。

【题解】P8338 [AHOI2022] 排列(数学,质因数分解,lcm)相关推荐

  1. java 判断一个数是正整数_【Java】P1075 质因数分解—关于数学方法在解题中的运用—(OJ:洛谷)...

    点击上方"蓝字"关注我们了解更多算法思路01题目 题目来源:洛谷OJ 题目链接: https://www.luogu.com.cn/ 题目描述 已知正整数n是两个不同的质数的乘积, ...

  2. 数学概念——J - 数论,质因数分解

    J - 数论,质因数分解 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit ...

  3. 火车进出栈问题(高精度+压位+质因数分解消除除法)

    题目描述 一列火车n节车厢,依次编号为1,2,3,-,n. 每节车厢有两种运动方式,进栈与出栈,问n节车厢出栈的可能排列方式有多少种. 输入格式 输入一个整数n,代表火车的车厢数. 输出格式 输出一个 ...

  4. upc组队赛16 GCDLCM 【Pollard_Rho大数质因数分解】

    GCDLCM 题目链接 题目描述 In FZU ACM team, BroterJ and Silchen are good friends, and they often play some int ...

  5. 机器学习中的数学——特征分解

    分类目录:<算法设计与分析>总目录 许多数学对象可以通过将它们分解成多个组成部分或者找到它们的一些属性而更好地理解,这些属性是通用的,而不是由我们选择表示它们的方式产生的.例如,整数可以分 ...

  6. 素数、最大公约数、最下公倍数、质因数分解

    2013-08-18 11:20:43 素数.最大公约数.最下公倍数.质因数分解都是与素数相关的,解决了素数的问题,其他的都可以此为基础求解. 小结: 求1到n之间的素数的基本方法是通过遍历2到sqr ...

  7. C++实现质因数分解

    质数(prime number)又称素数,有无限个.一个大于1的自然数,除了1和它本身外,不能被其他自然数整除(除0以外)的数称之为素数(质数):否则称为合数.根据算术基本定理,每一个比1大的整数,要 ...

  8. 3164 质因数分解

    3164 质因数分解  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 黄金 Gold 题解 题目描述 Description (多数据)给出t个数,求出它的质因子个数. 数据没 ...

  9. codevs 3164 质因数分解

    3164 质因数分解  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description (多数据)给出t个数,求出它的质因子个 ...

最新文章

  1. Android Bitmap圆角
  2. 驰骋工作流引擎的流程属性-节点属性-前台操作
  3. python验证用户登录的判断_python怎么判断用户是否登录?
  4. Magento学习手记(第十天)
  5. python将一个列表里面的某类元素取出来_03|Python列表常见操作
  6. “数据资产化”线上论坛圆满结束!
  7. 收藏 | 神经网络debug 6大技巧!
  8. go语言 slice
  9. JUnit5 @Tag注解示例
  10. graphviz python_工具推荐|我是如何使用Python脚本分析CPU使用情况的?
  11. jquery选择器的总结
  12. html 英文字母不换行,css如何设置英文单词不换行?
  13. 51Nod-1019 逆序数【逆序偶+归并排序】
  14. 数据平面可编程与SDN关系理解,以及数据平面可编程的理解
  15. DirectX编程:[初级]C#中利用DirectSound播放WAV格式声音[最少只要4句话]
  16. python的装饰器和find函数的使用
  17. matlab中怎么找晶闸管,matlab中晶闸管如何连接
  18. 高等数学张宇18讲 第十八讲 第二型曲线曲面积分
  19. CPU的内部架构和工作原理(简介)
  20. css3 cale()属性介绍以及自适应布局使用方法

热门文章

  1. 一周自学动态网站设计
  2. 自动化测试系列(六)--自动化成熟度等级
  3. win7网络看到部分其他计算机ip通,win7肿么查看同一个局域网内其他电脑IP?
  4. pivot和unpivot函数
  5. Xubuntu虚拟机系统终端下载速度太慢解决方法
  6. 周文洁 html5,清华大学出版社-图书详情-《JavaScript与jQuery网页前端开发与设计》...
  7. Android 实现视屏播放器、边播边缓存功能,附源码
  8. 模仿新浪微博字数限制提示
  9. 本地windows连接阿里云服务器
  10. js检查字符串字节长度