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

来源:互联网 发布:看门狗画面优化补丁 编辑:程序博客网 时间:2024/06/06 02:07

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

T1 天天去哪吃

#include <bits/stdc++.h>using namespace std;#define ll long long#define inf 0x3f3f3f3f#define N 100010inline 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 100010inline 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 200010inline 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]-1bool 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;}