NOIP模拟赛15

NOIP2017金秋冲刺训练营杯联赛模拟大奖赛第一轮Day1

 

T1 天天去哪儿吃

直接枚举

#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]);
}
View Code

 

T2 天天和树tree

找除去最长链之后的最长半链

3遍dfs即可

#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);
}
View Code

 

T3 摆摊

求区间的mex,主席树

防止出现0,1,,开始在1号位置加入一个无穷大

#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);
    }
}
View Code

 

posted @ 2017-09-26 17:55  TRTTG  阅读(294)  评论(0编辑  收藏  举报