https://www.luogu.org/problemnew/show/P3960

p<=500 50分 模拟

每个人的出队只会影响当前行和最后一列

p<=500,有用的行只有500行

所以只维护这p行和最后一列的信息

然后模拟

时间复杂度:O(p*(n+m))

空间复杂度:O(p*m+n)

#include<cstdio>
#include<iostream>
#include<algorithm>using namespace std;#define N 501
#define M 50001typedef long long LL;LL pos[N][M],last[M];struct node
{int x,y;
}e[N];int h[N];void read(int &x)
{x=0; char c=getchar();while(!isdigit(c)) c=getchar();while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
}int main()
{int n,m,q;read(n); read(m); read(q);for(int i=1;i<=q;++i) {read(e[i].x);read(e[i].y);h[i]=e[i].x;}sort(h+1,h+q+1);int tot=unique(h+1,h+q+1)-h-1;LL t;for(int i=1;i<=tot;++i){t=(LL)(h[i]-1)*m;for(int j=1;j<=m;++j) pos[i][j]=++t;}for(int i=1;i<=n;++i) last[i]=last[i-1]+m;int nx;LL ans;for(int i=1;i<=q;++i){nx=lower_bound(h+1,h+tot+1,e[i].x)-h;if(e[i].y==m) ans=last[h[nx]];else ans=pos[nx][e[i].y];cout<<ans<<'\n';if(e[i].y!=m){for(int j=e[i].y;j<m-1;++j) pos[nx][j]=pos[nx][j+1];pos[nx][m-1]=last[h[nx]];}for(int j=h[nx];j<n;++j) last[j]=last[j+1];last[n]=ans;}
}

View Code

x=1

x=1,全部的操作只涉及第一行和最后一列

用数据结构分别维护第一行A和最后一列B

每次的出队相当于查询A中的第k个元素

然后B中末尾插入一个数

当A中不足k个元素时,到B中查第k-|A|个元素

30分 线段树

A中以第i个数的值作为下标

B中以第i个数被插入到B中的顺序作为下标,另用a数组存它的值

#include<cstdio>
#include<vector>
#include<iostream>
#include<algorithm>using namespace std;#define N 300001typedef long long LL;int n;int sum[N<<2];LL a[N<<1];
int sum2[N<<3];void read(int &x)
{x=0; char c=getchar();while(!isdigit(c)) c=getchar();while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
}void build(int k,int l,int r)
{sum[k]=r-l+1;if(l==r)  return; int mid=l+r>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);
}int query(int k,int l,int r,int pos)
{if(l==r) return l;int mid=l+r>>1;if(pos<=sum[k<<1]) return query(k<<1,l,mid,pos);return query(k<<1|1,mid+1,r,pos-sum[k<<1]);
}void change(int k,int l,int r,int pos)
{if(l==r){sum[k]=0;return;}int mid=l+r>>1;if(pos<=mid) change(k<<1,l,mid,pos);else change(k<<1|1,mid+1,r,pos);sum[k]=sum[k<<1]+sum[k<<1|1];
}void build2(int k,int l,int r)
{if(l==r) {if(l<=n) sum2[k]=1;return;}int mid=l+r>>1;build2(k<<1,l,mid);build2(k<<1|1,mid+1,r);sum2[k]=sum2[k<<1]+sum2[k<<1|1];
}int query2(int k,int l,int r,int pos)
{if(l==r) return l;int mid=l+r>>1;if(pos<=sum2[k<<1]) return query2(k<<1,l,mid,pos);return query2(k<<1|1,mid+1,r,pos-sum2[k<<1]);
}void change2(int k,int l,int r,int pos,int w)
{if(l==r){sum2[k]=w;return;}int mid=l+r>>1;if(pos<=mid) change2(k<<1,l,mid,pos,w);else change2(k<<1|1,mid+1,r,pos,w);sum2[k]=sum2[k<<1]+sum2[k<<1|1];
}int main()
{int m,q;read(n); read(m); read(q);build(1,1,m-1);int i=1; LL j=m;for(;i<=n;j+=m,++i) a[i]=j;build2(1,1,n+q);int x,y;  LL ans; for(int i=1;i<=q;++i){read(x); read(y);if(y<=sum[1]){ans=query(1,1,m-1,y);cout<<ans<<'\n';change(1,1,m-1,ans);change2(1,1,n+q,n+i,1);a[n+i]=ans;}else{y-=sum[1];y=query2(1,1,n+q,y);cout<<a[y]<<'\n';change2(1,1,n+q,y,0);change2(1,1,n+q,n+i,1);a[n+i]=a[y];}}
}

View Code

30分 树状数组

另一种求解方式,下面100分线段树方法于此类似

两个树状数组,树状数组c1维护第1行,树状数组c2一个维护最后1列

0 1 分别表示这个位置有没有数

这样就可以使用树桩数组查询第k个数

在树状数组内二分即可

用两个vector 记录后添加进树状数组中的数

开始树状数组是满的,即c1有第一行的所有数,c2有最后一列的所有数

(x,y)出队

如果y=m,那么到c2中找第1个元素t

若t<=n 输出m*x,c2的末尾加入t

否则 到对应的vector中找第 t-n-1(下标从0开始)个输出,

输出的值插入到c2的末尾

如果y!=m,到c1中找第y个元素t

若t<=m-1 输出t

否则到对应的vector中找第t-m(下标从0开始)个输出

输出的值插入到c2的末尾

#include<cstdio>
#include<vector>
#include<iostream>
#include<algorithm>#define N 300001using namespace std;typedef long long LL;#define lowbit(x) x&-xint n,m,q,mx;int c1[N<<1],c2[N<<1];
int siz_c1,siz_c2;vector<LL>V[2];int l,r,mid,tmp;void read(int &x)
{x=0; char c=getchar();while(!isdigit(c)) c=getchar();while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
}void add(int *c,int x,int w)
{while(x<=mx){c[x]+=w;x+=lowbit(x);}
}int ask(int *c,int x)
{int sum=0;while(x){sum+=c[x];x-=lowbit(x);}return sum;
}LL work2(int x,LL y)
{l=1; r=mx;while(l<=r){mid=l+r>>1;if(ask(c2,mid)>=x) tmp=mid,r=mid-1;else l=mid+1;}add(c2,tmp,-1);LL ans=tmp<=n ? (LL)tmp*m : V[1][tmp-n-1];add(c2,++siz_c2,1);V[1].push_back(y ? y : ans);return ans;
}LL work1(int x,int y)
{l=1; r=mx;while(l<=r){mid=l+r>>1;if(ask(c1,mid)>=y) tmp=mid,r=mid-1;else l=mid+1;}add(c1,tmp,-1);LL ans=tmp<m ? tmp : V[0][tmp-m];add(c1,++siz_c1,1);V[0].push_back(work2(x,ans));return ans;
}int main()
{read(n); read(m); read(q);mx=max(m,n)+q;for(int i=1;i<m;++i) add(c1,i,1);for(int i=1;i<=n;++i) add(c2,i,1);siz_c1=m-1; siz_c2=n;int x,y; for(int i=1;i<=q;++i){read(x); read(y);if(y==m) cout<<work2(x,0)<<'\n';else cout<<work1(x,y)<<'\n';}
}

View Code

30分 splay

第一行splay0,最后一列splay1

裸地splay删除、查询k值、添加

查询(x,y)

如果y==m,splay1中找到第1个,输出,删除,加到最后面

否则,splay0中找到第y个,输出,从splay0中删除,加到splay1中;找到splay1中第1个,删除,加到splay0中

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;#define N 300001typedef long long LL;LL a[N];void read(int &x)
{x=0; char c=getchar();while(!isdigit(c)) c=getchar();while(isdigit(c))  { x=x*10+c-'0'; c=getchar(); }
}struct SPLAY
{int root,tot;int fa[N<<1],ch[N<<1][2];int siz[N<<1];LL num[N<<1];void build(int l,int r,int f,LL *a){if(l>r) return;int mid=l+r>>1;fa[mid]=f;ch[f][mid>f]=mid;num[mid]=a[mid];siz[mid]=1;build(l,mid-1,mid,a);build(mid+1,r,mid,a);siz[mid]=siz[ch[mid][0]]+siz[ch[mid][1]]+1;}void update(int x){siz[x]=1;if(ch[x][0]) siz[x]+=siz[ch[x][0]];if(ch[x][1]) siz[x]+=siz[ch[x][1]];}bool getson(int x){return ch[fa[x]][1]==x;}void rotate(int x){int y=fa[x],z=fa[y],k=getson(x);if(y!=root) ch[z][ch[z][1]==y]=x;ch[y][k]=ch[x][k^1]; ch[x][k^1]=y;fa[x]=z; fa[y]=x; fa[ch[y][k]]=y;update(y);}void splay(int x){for(int f;f=fa[x];rotate(x))if(fa[f]) rotate(getson(x)==getson(f) ? f : x);update(x);root=x;}void insert_last(LL x){if(!root){root=++tot;num[tot]=x;siz[tot]=1;return;}int now=root;while(ch[now][1]) now=ch[now][1];ch[now][1]=++tot;fa[tot]=now;num[tot]=x;siz[tot]=1;splay(tot);}int find_kth(int x){int now=root;while(1){if(siz[ch[now][0]]+1==x) return now;if(ch[now][0] && siz[ch[now][0]]>=x){now=ch[now][0];continue;}x-=siz[ch[now][0]]+1;now=ch[now][1];}}int getpre(){int now=ch[root][0];while(ch[now][1]) now=ch[now][1];return now;}void del(){if(!ch[root][0] && !ch[root][1]){root=0;return;}if(!ch[root][0]){root=ch[root][1];fa[root]=0;return;}if(!ch[root][1]){root=ch[root][0];fa[root]=0;return;}int pre=getpre();int tmp=root;splay(pre);ch[root][1]=ch[tmp][1];fa[ch[root][1]]=root;update(root);}}Splay[2];int main()
{int n,m,q;read(n); read(m); read(q);int i; LL j;for(i=1;i<m;++i)  a[i]=i;Splay[0].build(1,m-1,0,a);Splay[0].tot=m-1;Splay[0].root=m>>1;for(i=1,j=m;i<=n;++i,j+=m) a[i]=j;Splay[1].build(1,n,0,a);Splay[1].tot=n;Splay[1].root=n+1>>1; int x,y; int id0,id1;for(i=1;i<=q;++i){read(x);read(y);if(y==m){id0=Splay[1].find_kth(1);Splay[1].splay(id0);Splay[1].del();Splay[1].insert_last(Splay[0].num[id0]);cout<<Splay[1].num[id0];continue;}id0=Splay[0].find_kth(y);Splay[0].splay(id0);Splay[0].del();Splay[1].insert_last(Splay[0].num[id0]);id1=Splay[1].find_kth(x);Splay[1].splay(id1);Splay[1].del();Splay[0].insert_last(Splay[1].num[id1]);cout<<Splay[0].num[id0]<<'\n';}
}

View Code

满分做法

与x=1的做法类似

我们只需要用n个数据结构Ai维护每一行的前m-1个

再用一个数据结构B维护最后一列即可

注意所选数据结构的空间问题

每一次查询(x,y)

如果y不是最后一列,就从Ax中找到第y个元素,记为ans,输出ans,Ax中删去ans,

把B中的第x个元素插到Ax的最后面,把ans插到B的最后面

如果y是最后一列,在B中找到第y个元素,记为ans,输出ans,B中删去ans

把ans插入到B的最后一个

100分 线段树

对于每一行维护一个线段树

显然不能提前都开满,所以动态开节点

线段树区间维护的大小固定,所以动态删除和动态添加不是很方便

所以不直接执行删除操作,不在线段树上添加

开始我们默认维护前n行m-1列的线段树中所有节点都是满的

维护最后一列的线段树也是满的

删除操作:

用sum[k]记录下k包含的这段区间删除的数的个数

这样查询时,当前区间数的个数 为区间大小-sum[k]

如果要查的数<=区间大小-sum[k] 到左孩子查

否则,查的数减去 区间大小-sum[k] ,到右孩子查

添加操作:

令开n+1个vector,存储动态添加到对应线段树里的数

查询操作:

如果y=m,

假设维护最后一列的线段树是第n+1颗

查询第n+1颗线段树里第x个值pos

若pos<=n,输出 pos*m,

否则输出第n+1个vector里第pos-n-1(下标从0开始)个元素

输出的值插入到最后一列的线段树的末尾

如果y!=m

到第x颗线段树里查询第y个数pos

若pos<=m-1,输出(x-1)*m+pos,

否则输出第x个vector里 第pos-m(下标从0开始)个元素

输出的值插入到最后一列线段树的末尾

#include<cstdio>
#include<vector>
#include<iostream>
#include<algorithm>using namespace std;#define N 300001typedef long long LL;int n,m,q,mx;int tot;
int root[N+1],lc[N*20],rc[N*20];
int sum[N*20];int pos;vector<LL>V[N];void read(int &x)
{x=0; char c=getchar();while(!isdigit(c)) c=getchar();while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
}int query(int k,int l,int r,int w)
{if(l==r) return l;int mid=l+r>>1,tmp=mid-l+1-sum[lc[k]];if(w<=tmp) return query(lc[k],l,mid,w);return query(rc[k],mid+1,r,w-tmp);
}void change(int &k,int l,int r)
{if(!k) k=++tot;sum[k]++;if(l==r) return;int mid=l+r>>1;if(pos<=mid) change(lc[k],l,mid);else change(rc[k],mid+1,r);
}LL work0(int x,LL y)
{pos=query(root[n+1],1,mx,x);change(root[n+1],1,mx);LL ans=pos<=n ? (LL)pos*m : V[n+1][pos-n-1];V[n+1].push_back(y ? y : ans);return ans;
}LL work1(int x,int y)
{pos=query(root[x],1,mx,y);change(root[x],1,mx);LL ans=pos<m ? (LL)(x-1)*m+pos : V[x][pos-m];V[x].push_back(work0(x,ans));return ans;
}int main()
{read(n); read(m); read(q);mx=max(n,m)+q;int x,y;while(q--){read(x); read(y);if(y==m) cout<<work0(x,0)<<'\n';else cout<<work1(x,y)<<'\n';}
}

View Code

100分 树状数组

树状数组不能动态开节点

30分树状数组做法中,树状数组的作用是查询k值

在这里我们仍然只用树状数组查询k值

我们不存储没有离队过的元素,因为知道了它一开始在第i行第j列后就可以得出它的编号是(i-1)*m+j

而会离队的元素至多只有q个

所以对于每一行的前m-1列和最后一列都开一个vector Ai,B,记录本行或最后一列补进来的编号

每次询问的(x,y)是第j个出现在第x行的数只与 这次询问之前对第x行进行的询问有关

默认原来队列中的数是第1到m个出现在本行的数

那就可以读入所有数据,离线处理

若我们能够处理出每一个查询(x,y)应该是第几个出现在第x行的数,记为pre[i]

然后按输入顺序枚举每一个询问(x,y)

若y!=m,2个操作:

1、第x行第pre[i]个数出队,到最后一列的最后一个位置,即vector B中加入第x行第pre[i]个数

2、第x行最后补上最后一列的第x个数,即vector Ax 中加入 最后一列的第x个数

若y==m,

最后一列的第x个数出队,到最后一列末尾,vector B中加入最后一列第x个数

如何得到 最后一列的第x个数?

树状数组维护最后一列,每查询一次(x,y),标记一次x

对于树状数组中查到的第x个数h,意为是第h个出现在最后一列的数

若h<=n,则为h*m

若h>m,那就是vector B 中第h-n-1(下标从0开始)个元素

如何得到第x行第pre[i]个出现的数?

若pre[i]<m,就是(x-1)*m+pre[i]

若pre[i]>=m,就是vector Ax 中 第pre[i]-m(下标从0开始)个出现的数

如何得到第i个询问(x,y)的pre[i]?

枚举每一行,

在树状数组中二分出第y个数在哪个位置

处理一个,树状数组中删一个

处理完一行之后,再把之前删的都加回来供下一行使用

这样我们就得到了每一个查询(x,y)应该是第几个出现在第x行的数

#include<cstdio>
#include<vector>
#include<iostream>
#include<algorithm>using namespace std;#define N 300001typedef long long LL;#define lowbit(x) x&-xint mx;
int n,m,q;struct node
{int pos,id;node(int pos_=0,int id_=0) : pos(pos_),id(id_)  { }};
vector<node>V[N];
vector<LL>num[N];int c[N<<1];int qx[N],qy[N];int pre[N];void read(int &x)
{x=0; char c=getchar();while(!isdigit(c)) c=getchar();while(isdigit(c))  { x=x*10+c-'0'; c=getchar(); }
}void add(int x,int w)
{while(x<=mx){c[x]+=w;x+=lowbit(x);}
}int ask(int x)
{int sum=0;while(x){sum+=c[x];x-=lowbit(x);}return sum;
}int query_kth(int k)
{  int l=0,r=mx;int mid,tmp;while(l<=r){mid=l+r>>1;if(ask(mid)>=k) tmp=mid,r=mid-1;else l=mid+1;}return tmp;
}void init()
{read(n); read(m); read(q);mx=max(n,m)+q;for(int i=1;i<=q;++i){read(qx[i]); read(qy[i]);if(qy[i]!=m) V[qx[i]].push_back(node(qy[i],i));}
}void solve1()
{for(int i=1;i<=mx;++i) add(i,1);int siz;node now;for(int i=1;i<=n;++i){siz=V[i].size();for(int j=0;j<siz;++j){now=V[i][j];pre[now.id]=query_kth(now.pos);add(pre[now.id],-1);}for(int j=0;j<siz;++j) add(pre[V[i][j].id],1);}
}void solve2()
{LL ans; int h;for(int i=1;i<=q;++i){h=query_kth(qx[i]);ans= h<=n ? (LL)h*m : num[0][h-n-1];add(h,-1);if(qy[i]!=m){num[qx[i]].push_back(ans);ans= pre[i]<m ? LL(qx[i]-1)*m+pre[i] : num[qx[i]][pre[i]-m];}num[0].push_back(ans);cout<<ans<<'\n';}
}int main()
{init();solve1();solve2();
}

View Code

100分 splay

没有用到的区间都压缩成一个大节点

每一行一个splay,最后一列一个splay

刚开始每一行的前m-1列都压缩成一个点

最后一列的splay把元素填进去

与30分不同的是查询的时候需要分裂节点

#include<cstdio>
#include<iostream>using namespace std;#define N 300001typedef long long LL;int tot;int root[N];
int l[N*6],r[N*6];int ch[N*6][2],fa[N*6],siz[N*6],key[N*6];
LL num[N*6];int rt;LL a[N];void read(int &x)
{x=0; char c=getchar();while(!isdigit(c)) c=getchar();while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
}void build(int l,int r,int f)
{if(l>r) return;int mid=l+r>>1;fa[mid]=f;ch[f][mid>f]=mid;key[mid]=siz[mid]=1;num[mid]=a[mid];build(l,mid-1,mid);build(mid+1,r,mid);siz[mid]=siz[ch[mid][0]]+siz[ch[mid][1]]+1;
}bool getson(int x)
{return ch[fa[x]][1]==x;
}void update(int x)
{siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+key[x];
}void rotate(int x,int &goal)
{int y=fa[x],z=fa[y]; bool k=getson(x);if(y!=goal) ch[z][ch[z][1]==y]=x;else goal=x;ch[y][k]=ch[x][k^1];ch[x][k^1]=y;fa[x]=z; fa[y]=x; fa[ch[y][k]]=y;update(y);
}void splay(int x,int &goal)
{int y;while(x!=goal){y=fa[x];if(y!=goal) rotate(getson(x)==getson(y) ? y : x,goal);rotate(x,goal);}update(x);
}void split(int now,int k,int id)
{if(k<=siz[ch[now][0]]) split(ch[now][0],k,id);else if(k>siz[ch[now][0]]+key[now]) split(ch[now][1],k-siz[ch[now][0]]-key[now],id);else{k-=siz[ch[now][0]];if(k!=1){fa[ch[++tot][0]=ch[now][0]]=tot;  fa[ch[now][0]=tot]=now;key[tot]=k-1; key[now]-=k-1;l[tot]=l[now]; r[tot]=l[now]+key[tot]-1;l[now]=r[tot]+1;update(tot);}if(key[now]!=1){fa[ch[++tot][1]=ch[now][1]]=tot;fa[ch[now][1]=tot]=now;key[tot]=key[now]-1;key[now]=1;l[tot]=l[now]+1;r[tot]=r[now];r[now]=l[now];update(tot);}splay(now,root[id]);}
}void insert_last(int &rt,LL x)
{if(!rt){rt=++tot;l[tot]=r[tot]=key[tot]=siz[tot]=1;num[tot]=x;return;}int now=rt;while(ch[now][1]) now=ch[now][1];fa[++tot]=now;ch[now][1]=tot;l[tot]=r[tot]=key[tot]=siz[tot]=1;num[tot]=x;splay(tot,rt);
}int find_kth(int now,int x)
{while(1){if(x<=siz[ch[now][0]]){now=ch[now][0];continue;}x-=siz[ch[now][0]];if(x==1) return now;x--;now=ch[now][1];}
}int find_pre(int rt)
{int now=ch[rt][0];while(ch[now][1]) now=ch[now][1];return now;
}void del(int &rt)
{if(!ch[rt][0] && !ch[rt][1]){rt=0;return;}if(!ch[rt][0]){rt=ch[rt][1];return;}if(!ch[rt][1]){rt=ch[rt][0];return;}int pre=find_pre(rt);int tmp=rt;splay(pre,rt);ch[rt][1]=ch[tmp][1];fa[ch[rt][1]]=rt;update(rt);
}int main()
{int n,m,q;read(n); read(m); read(q);int i; LL j;for(i=1,j=m;i<=n;++i,j+=m) a[i]=j;build(1,n,0);tot=n;root[0]=n+1>>1;for(int i=1;i<=n;++i){root[i]=++tot;siz[tot]=m-1;key[tot]=m-1;l[tot]=1; r[tot]=m-1;}int x,y; LL ans;int tmp;while(q--){read(x); read(y);tmp=find_kth(root[0],x);splay(tmp,root[0]);del(root[0]);if(y!=m){split(root[x],y,x);ans=num[root[x]] ? num[root[x]] : (LL)(x-1)*m+l[root[x]];del(root[x]);insert_last(root[0],ans);insert_last(root[x],num[tmp]);}else{ans=num[tmp];insert_last(root[0],ans);}cout<<ans<<'\n';}
}

View Code

转载于:https://www.cnblogs.com/TheRoadToTheGold/p/8214795.html

NOIP2017 列队相关推荐

  1. NOIP2017 列队——动态开点线段树

    Description: Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n×m名学生,方阵的行数为  ...

  2. [noip2017]列队 splay

    noip出这个题简直丧心病狂,省选都没考过这么恶心的splay 这个题思路不是很难找,要点只有两个:特殊数据和动态结构 首先纵向发生变化的一定是最右边的一列,所以它是特殊的 然后询问只有1e5 ,而矩 ...

  3. 【学习笔记】Splay

    普通平衡树 模板题链接 1.引入 一种二叉树,这棵树满足任意一个节点,它的左儿子的权值<自己的权值<右儿子的权值 这种树叫做二叉查找树,这个概念应该在初赛中见过了吧 Splay就是利用这个 ...

  4. Noip前的大抱佛脚----赛前任务

    赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...

  5. OI每周刷题记录——lrllrl

    看这标题就知道我是模仿的hzwer大佬,远程%%% 大佬的OI经历让蒟蒻我深受感触,为了晚一些AFO本蒟蒻也得加油了 从高二上期第一周开始计数,每个星期天更一次,一直更到我AFO 如果这是我此生最后一 ...

  6. 【NOIP题解】NOIP2017 TG D2T3 列队

    列队,NOIP2017 TG D2T3. 树状数组经典题. 题目链接:洛谷. 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. ...

  7. 【NOIP2017提高组】列队

    题目背景 NOIP2017提高组 DAY2 T3 题目描述 Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵.Sylvia 所在的方阵中 ...

  8. JZOJ 5478. 【NOIP2017提高组正式赛】列队

    Description Sylvia 是一个热爱学习的女孩子.前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia所在的方阵中有n × m名学生,方阵的行数为 n, ...

  9. 【NOIP2017提高组正式赛】列队

    题面 Description Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia所在的方阵中有n × m名学生,方阵的行数 ...

最新文章

  1. 2022-2028年中国塑料管的制造行业市场需求预测及投资策略研究报告
  2. ADO.NET连接SQL Server数据库
  3. 教你自己制作Vista与DOS双系统
  4. java堆内与堆外数据交互_Java:汇总堆外数据
  5. MySql应用原理分析系列文章目录
  6. Mr.J-- HTTP学习笔记(六)-- 代理
  7. J.U.C - AQS
  8. MySQL 刷脏页问题
  9. git 拉取某个分支到本地
  10. 扇贝有道每日一句180904
  11. 《Java高级Struts2》教学大纲(云计算) 版本号 编写人 版本描述 V1.0 目录 课程教学目标 5 (一)知识目标 5 (二)能力目标 6 (三)速度目标 6
  12. 最新emoji表情代码大全_如何给微信公众号菜单添加emoji(亲测有效)
  13. 将老电脑从windows xp系统升级到10//将win10 32位系统更为64位
  14. 智慧职教云答案在哪里找_云课堂智慧职教答案哪里找
  15. Ameya:蔡司激光共聚焦显微镜的优势特点及应用领域
  16. 电商销售分析之制作销售看板
  17. 从0开始制作简单的小程序AR
  18. 《我为什么熬夜?》系列之 倚天屠龙记
  19. 波克定律:好的想法必需经得起辩论
  20. 基于多阈值的形态提取遥感图像中的沿海线的特征方法(Qu Jishuang)

热门文章

  1. 中国工程院院士陈左宁详述:人工智能模型和算法的七大发展趋势
  2. 大佬共话AI:“三马二宏”等亮相2020年世界人工智能大会
  3. 国家计划统筹布局哪些人工智能创新平台?
  4. 京东果然发福了:宣布涨薪两个月! 2 年内将员工平均薪资涨至 16 薪
  5. 程序员出身,身价 340 亿!没有他,可能我们刷不了 B 站
  6. 刷爆全网的动态条形图,原来 5 行 Python 代码就能实现!
  7. 互联网人的平均时长,居然这么短...
  8. 马云的 ATM 梦实现了
  9. 坦白讲!做 Java 工程师,挺好!
  10. 20年前的程序员什么样?从版主到架构大牛的成长之路