NowCoder 9.9 模拟赛

T1.中位数

二分答案x,原序列大于x的置为1,小于x的置为-1,判断是否存在长度大于m的区间和大于0(也就是大于x的数多于小于x的数),若有,则ans>=x,否则ans<x

#include<iostream>
#include<cstdio>

using namespace std;

inline int rd(){
  int ret=0,f=1;char c;
  while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
  while(isdigit(c))ret=ret*10+c-'0',c=getchar();
  return ret*f;
}

const int MAXN=100005;

int n,m;

int a[MAXN],b[MAXN];
bool check(int x){
  int mn=1<<30;
  for(int i=1;i<=n;i++)b[i]=a[i]<x?-1:1;
  for(int i=1;i<=n;i++){
    if(i>=m) mn=min(mn,b[i-m]);
    b[i]+=b[i-1];
    if(i>=m&&b[i]>mn)return 1;
  }
  return 0;
}

int main(){
  n=rd();m=rd();
  int l=0,r=1<<29,mid,ans;
  for(int i=1;i<=n;i++) a[i]=rd();
  while(l<=r){
    mid=l+r>>1;
    if(check(mid))ans=mid,l=mid+1;
    else r=mid-1;
  }
  cout<<ans;
  return 0;
}
View Code

T2.数数字

数位DP还行,记忆化搜索实现

#include<iostream>
#include<cstdio>
#include<map>

using namespace std;

typedef long long ll;

inline ll rd(){
  ll ret=0,f=1;char c;
  while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
  while(isdigit(c))ret=ret*10+c-'0',c=getchar();
  return ret*f;
}

const int MAXN=128;

int a[MAXN];
ll l,r,l1,r1;
map<ll,ll> mp[MAXN];

ll dfs(int cur,ll sum,ll lim,ll xzero){
  if(!cur){
    if(xzero) sum=0;
    return (l1<=sum&&sum<=r1);
  }
  if(!xzero&&!lim&&mp[cur].count(sum))return mp[cur][sum];
  ll ret=0;
  int mx=9;
  if(lim)mx=a[cur];
  for(int i=0;i<=mx;i++){
    if(xzero)ret+=dfs(cur-1,(i==0)?1ll:i*1ll,lim&&(i==mx),xzero&&(i==0));
    else ret+=dfs(cur-1,sum*1ll*i,lim&&(i==mx),xzero&&(i==0));
  }
  if(!xzero&&!lim)mp[cur][sum]=ret;
  return ret;
}

ll solve(ll x){
  int cnt=0;
  while(x){
    a[++cnt]=x%10;
    x/=10;
  }
  return dfs(cnt,1,1,1);
}


int main(){
  l=rd();r=rd();l1=rd();r1=rd();
  cout<<solve(r)-solve(l-1);
  return 0;
}
View Code

T3.保护

ErkkiErkko的主席树想法

#include<iostream>
#include<cstdio>
#include<vector>

using namespace std;

inline int rd(){
  int ret=0,f=1;char c;
  while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
  while(isdigit(c))ret=ret*10+c-'0',c=getchar();
  return ret*f;
}

const int MAXN=200005;

int n,m,q;
vector<int> vec[MAXN];

int rt[MAXN];

struct Edge{
  int next,to;
}e[MAXN<<1];
int ecnt,head[MAXN];
inline void add(int x,int y){
  e[++ecnt].next = head[x];
  e[ecnt].to = y;
  head[x] = ecnt;
}

int fa[MAXN],hson[MAXN],siz[MAXN],dep[MAXN];
int top[MAXN],id[MAXN],tim=0;
int ll[MAXN],rr[MAXN];
void dfs1(int x,int pre){
  fa[x]=pre;siz[x]=1;dep[x]=dep[pre]+1;
  ll[x]=++tim;id[tim]=x;
  int mx=0;
  for(int i=head[x];i;i=e[i].next){
    int v=e[i].to;
    if(v==pre) continue;
    dfs1(v,x);siz[x]+=siz[v];
    if(siz[v]>mx){mx=siz[v];hson[x]=v;}
  }
  rr[x]=tim;
}

void dfs2(int x,int tp){
  top[x]=tp;
  if(hson[x])dfs2(hson[x],tp);
  for(int i=head[x];i;i=e[i].next){
    int v=e[i].to;
    if(v==fa[x]||v==hson[x]) continue;
    dfs2(v,v);
  }
}
int lca(int x,int y){
  while(top[x]!=top[y]){
    if(dep[top[x]]<dep[top[y]])swap(x,y);
    x=fa[top[x]];
  }
  return dep[x]<=dep[y]?x:y;
}
int ch[MAXN*40][2],val[MAXN*40],tot;
void update(int x,int &cur,int l,int r){
  int f=cur;cur=++tot;val[cur]=val[f]+1;
  ch[cur][0]=ch[f][0];ch[cur][1]=ch[f][1];
  if(l==r)return;
  int mid=l+r>>1;
  if(x<=mid)update(x,ch[cur][0],l,mid);
  else update(x,ch[cur][1],mid+1,r);
}
int query(int cur,int l,int r,int f,int K){
  if(val[f]-val[cur]<K) return -1;
  if(l==r)return l;
  int mid=l+r>>1;
  if(K<=val[ch[f][0]]-val[ch[cur][0]])
    return query(ch[cur][0],l,mid,ch[f][0],K);
  return query(ch[cur][1],mid+1,r,ch[f][1],K-(val[ch[f][0]]-val[ch[cur][0]]));
}

int main(){
  int x,y;
  n=rd();m=rd();
  for(int i=1;i<n;i++){
    x=rd();y=rd();add(x,y);add(y,x);
  }
  dfs1(1,0);dfs2(1,1);
  for(int i=1;i<=m;i++){
    x=rd();y=rd();
    int z=lca(x,y);
    vec[x].push_back(dep[z]);
    vec[y].push_back(dep[z]);
  }
  for(int i=1;i<=n;i++){
    rt[i]=rt[i-1];
    int up=vec[id[i]].size();
    for(int j=0;j<=up-1;j++){
      update(vec[id[i]][j],rt[i],1,n);
      }
  }
  q=rd();
  int ans=0;
  for(int i=1;i<=q;i++){
    x=rd();y=rd();
    if(!y)ans=dep[x]-dep[1];
    else{
      int tmp=query(rt[ll[x]-1],1,n,rt[rr[x]],y);
      if(tmp==-1||tmp>=dep[x])ans=0;
      else ans=dep[x]-tmp;
    }
    printf("%d
",ans);
  }
}
View Code

 

未经许可,禁止搬运。
原文地址:https://www.cnblogs.com/ghostcai/p/9613823.html