NOIP模拟9.16(TYVJ NOIP2017模拟赛D1)

123 篇文章 0 订阅
104 篇文章 0 订阅

T1.天天去哪吃。(模拟)AC。
T2.天天和树。(求树的直径)瞎搞了70.
T3.摆摊。(类似mex,离线+线段树)瞎搞了70.

T1 天天去哪吃

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 100010
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-'0',ch=getchar();
    return x*f;
}
int n,m,k,ans[N<<1];
ll a,b;
bool f[N];
void solve0(){
    for(int i=3;i<=m;++i){
        if(i-1>k) f[ans[i-1-k]]=0;
        int x=(a*ans[i-1]+b*ans[i-2])%n;
        while(f[x]) x=(x+1)%n;
        ans[i]=x;f[x]=1;
    }
    for(int i=3;i<=m;++i) printf("%d ",ans[i]);
}
int main(){
    freopen("lunch.in","r",stdin);
    freopen("lunch.out","w",stdout);
    n=read();m=read();a=read();b=read();ans[1]=read();ans[2]=read();
    k=n/2;f[ans[1]]=1;f[ans[2]]=1;
    solve0();
    return 0;
}

T2 天天和树

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 100010
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-'0',ch=getchar();
    return x*f;
}
int n,h[N],num=0,d[N],fa[N],dep[N];
bool vis[N];
struct edge{
    int to,next;
}data[N<<1];
void bfs(int x){
    queue<int>q;
    memset(vis,0,sizeof(vis));
    q.push(x);vis[x]=1;d[x]=0;
    while(!q.empty()){
        int x=q.front();q.pop();
        for(int i=h[x];i;i=data[i].next){
            int y=data[i].to;if(vis[y]) continue;
            vis[y]=1;d[y]=d[x]+1;q.push(y);
        }
    }
}
void dfs(int x){
    for(int i=h[x];i;i=data[i].next){
        int y=data[i].to;
        if(fa[x]==y) continue;
        fa[y]=x;dep[y]=dep[x]+1;dfs(y);
    }
}
int main(){
    freopen("tree.in","r",stdin);
    n=read();
    for(int i=1;i<n;++i){
        int x=read(),y=read();
        data[++num].to=y;data[num].next=h[x];h[x]=num;
        data[++num].to=x;data[num].next=h[y];h[y]=num;
    }
    bfs(1);int root=0;
    for(int i=1;i<=n;++i) if(d[i]>d[root]) root=i;
    dfs(root);int pos=0;
    for(int i=1;i<=n;++i) if(dep[i]>dep[pos]) pos=i;
    queue<int>q;memset(vis,0,sizeof(vis));
    while(pos!=root) q.push(pos),d[pos]=0,vis[pos]=1,pos=fa[pos];
    q.push(root),d[root]=0,vis[root]=1;
    while(!q.empty()){
        int x=q.front();q.pop();
        for(int i=h[x];i;i=data[i].next){
            int y=data[i].to;if(vis[y]) continue;
            vis[y]=1;d[y]=d[x]+1;q.push(y);
        }
    }
    for(int i=1;i<=n;++i) if(d[i]>d[pos]) pos=i;
    printf("%d\n",d[pos]);
    return 0;
}

T3 摆摊

注意一下因为是求最小的连续两个整数,所以我们还要记一下a[i]+1和a[i]-1下一次出现的位置。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 200010
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-'0',ch=getchar();
    return x*f;
}
int n,m,a[N],qq,mex[N],ANS[N],last[N],next[N][3];//0--a[i],1--a[i]+1,2--a[i]-1
bool f[N];
struct que{
    int l,r,id;
}q[N];
struct node{
    int mn;
}tree[N<<2];
inline bool cmp(que x,que y){return x.l<y.l;}
void build(int p,int l,int r){
    tree[p].mn=inf;
    if(l==r){tree[p].mn=mex[l];return;}
    int mid=l+r>>1;
    build(p<<1,l,mid);build(p<<1|1,mid+1,r);
}
void update(int p,int l,int r,int x,int y,int val){
    if(x<=l&&r<=y){tree[p].mn=min(tree[p].mn,val);return;}
    int mid=l+r>>1;
    if(x<=mid) update(p<<1,l,mid,x,y,val);
    if(y>mid) update(p<<1|1,mid+1,r,x,y,val);
}
int query(int p,int l,int r,int x){
    if(l==r) return tree[p].mn;
    int mid=l+r>>1;
    if(x<=mid) return min(query(p<<1,l,mid,x),tree[p].mn);
    else return min(query(p<<1|1,mid+1,r,x),tree[p].mn);
}
int main(){
//  freopen("stall.in","r",stdin);
    n=read();m=read();qq=read();int ans=1;
    for(int i=1;i<=m;++i){
        a[i]=read();last[i]=m+1;f[a[i]]=1;
        while(f[ans]||f[ans+1]) ans++;
        mex[i]=ans;
    }
    for(int i=m;i>=1;--i){
        next[i][0]=last[a[i]];next[i][1]=last[a[i]+1];next[i][2]=last[a[i]-1];
        last[a[i]]=i;
    }
    for(int i=1;i<=qq;++i) q[i].l=read(),q[i].r=read(),q[i].id=i;
    sort(q+1,q+qq+1,cmp);build(1,1,m);int l=1;
    for(int i=1;i<=qq;++i){
        while(l<q[i].l){
            if(a[l]+1<=n)update(1,1,m,l+1,min(next[l][0],next[l][1])-1,a[l]);
            if(a[l]-1>=1)update(1,1,m,l+1,min(next[l][0],next[l][2])-1,a[l]-1);
            l++;
        }
        ANS[q[i].id]=query(1,1,m,q[i].r);
    }
    for(int i=1;i<=qq;i++) printf("%d %d\n",ANS[i],ANS[i]+1);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值