NOIP模拟赛15
NOIP2017金秋冲刺训练营杯联赛模拟大奖赛第一轮Day1
T1 天天去哪儿吃
直接枚举
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<algorithm> using namespace std; #define N 100001 int d[N<<1]; bool g[N]; int main() { int n,m; long long a,b; scanf("%d%d%lld%lld",&n,&m,&a,&b); scanf("%d%d",&d[1],&d[2]); int now; int len=n/2; for(int i=2;i>=max(3-len,1);i--) g[d[i]]=true; for(int i=3;i<=m;i++) { now=(a*d[i-1]+b*d[i-2])%n; while(g[now]) { now++; if(now==n) now=0; } d[i]=now; if(i-len>0) g[d[i-len]]=false; g[now]=true; } for(int i=3;i<=m;i++) printf("%d ",d[i]); }
T2 天天和树tree
找除去最长链之后的最长半链
3遍dfs即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<algorithm> #define N 100001 using namespace std; int front[N],nxt[N<<1],to[N<<1],tot; int maxn,wh1,wh2; int pre[N],d[N]; bool in[N]; void add(int u,int v) { to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; to[++tot]=u; nxt[tot]=front[v]; front[v]=tot; } void dfs1(int x,int fa,int dis) { if(dis>maxn) maxn=dis,wh1=x; for(int i=front[x];i;i=nxt[i]) if(to[i]!=fa) dfs1(to[i],x,dis+1); } void dfs2(int x,int fa,int dis) { pre[x]=fa; if(dis>maxn) maxn=dis,wh2=x; for(int i=front[x];i;i=nxt[i]) if(to[i]!=fa) dfs2(to[i],x,dis+1); } void dfs3(int x,int fa,int dis) { d[x]=dis; for(int i=front[x];i;i=nxt[i]) if(to[i]!=fa) dfs3(to[i],x,dis+1); } int main() { int n; scanf("%d",&n); int u,v; for(int i=1;i<n;i++) { scanf("%d%d",&u,&v); add(u,v); } dfs1(1,0,0); maxn=0; dfs2(wh1,wh1,0); in[wh1]=true; for(int i=wh2;i!=pre[i];i=pre[i]) in[i]=true; for(int i=1;i<=n;i++) if(in[i]) for(int j=front[i];j;j=nxt[j]) if(!in[to[j]]) dfs3(to[j],i,1); int ans=0; for(int i=1;i<=n;i++) ans=max(ans,d[i]); printf("%d",ans); }
T3 摆摊
求区间的mex,主席树
防止出现0,1,,开始在1号位置加入一个无穷大
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<algorithm> #define N 200011 using namespace std; int n,m,q,tot,a[N]; int root[N],lc[10000000],rc[10000000],minn[10000000]; void insert(int &x,int y,int l,int r,int pos,int w) { x=++tot; minn[x]=minn[y]; lc[x]=lc[y],rc[x]=rc[y]; if(l==r) { minn[x]=max(minn[x],w); return; } int mid=l+r>>1; if(pos<=mid) insert(lc[x],lc[y],l,mid,pos,w); else insert(rc[x],rc[y],mid+1,r,pos,w); minn[x]=min(minn[lc[x]],minn[rc[x]]); } int query(int x,int l,int r,int w) { if(l==r) return l; int mid=l+r>>1; if(minn[lc[x]]<w) return query(lc[x],l,mid,w); else return query(rc[x],mid+1,r,w); } int main() { scanf("%d%d%d",&n,&m,&q); insert(root[0],root[0],1,n+1,1,2e9); for(int i=1;i<=m;i++) { scanf("%d",&a[i]); insert(root[i],root[i-1],1,n+1,a[i],i); insert(root[i],root[i],1,n+1,a[i]+1,i); } int u,v,ans; while(q--) { scanf("%d%d",&u,&v); ans=query(root[v],1,n+1,u); if(ans==n+1) printf("-1 -1\n"); else printf("%d %d\n",ans-1,ans); } }