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;
}