codeforce 1217E 线段树乱搞

https://codeforces.com/contest/1217/problem/E

1.显然,最终的集合一定只包含2个元素

2.这两个元素一定是某一位上重叠的最小值和次小值

位数很小,最多10个

所以做法呼之欲出,开10棵树,分别维护每一个位上,存在值的所有数字中,最小的2个数字即可

#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pii pair<int,int>
#define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
using namespace std;//head
const int maxn=2e5+10,INF=1e9+10;
int casn,n,m,k;
namespace fastio{
bool isdigit(char c){return c>=48&&c<=57;}
const int maxsz=1e7;
class fast_iostream{public:
  char ch=get_char();
  bool endf=1,flag;
  char get_char(){
    static char buffer[maxsz],*a=buffer,*b=buffer;
    return b==a&&(b=(a=buffer)+fread(buffer,1,maxsz, stdin),b==a)?EOF:*a++;
  }
  template<typename type>bool get_int(type& tmp){
    flag=tmp=0;
    while(!isdigit(ch)&&ch!=EOF){flag=ch=='-';ch=get_char();};
    if(ch==EOF)return endf=0;
    do{tmp=ch-48+tmp*10;}while(isdigit(ch=get_char()));
    if(flag)tmp=-tmp;
    return 1;
  }
  template<typename type>fast_iostream& operator>>(type& tmp){get_int(tmp);return *this;}
};
}fastio::fast_iostream io;
pii add(pii a,pii b){
  if(a.fi>b.fi) a.se=a.fi,a.fi=b.fi;
  else if(a.se>b.fi) a.se=b.fi;
  if(a.fi>b.se) a.se=a.fi,a.fi=b.se;
  else if(a.se>b.se) a.se=b.se;
  return a;
}
int a[maxn][11];
class segtree{public:
#define nd  node[now]
#define ndl node[now<<1]
#define ndr node[now<<1|1]
  struct segnode {
    int l,r;pii mx;
    inline int mid(){return (r+l)>>1;}
  }node[maxn*3];
  void maketree(int s,int t,int k,int now=1){
    nd={s,t,mp(INF,INF)};
    if(s==t) {
      nd.mx=mp(a[s][k],INF);
      return ;
    }
    maketree(s,nd.mid(),k,now<<1);
    maketree(nd.mid()+1,t,k,now<<1|1);
    nd.mx=add(ndl.mx,ndr.mx);
  }
  void update(int pos,int x,int now=1){
    if(nd.l==nd.r){
       nd.mx=mp(x,INF);
       return ;
    }
    if(pos<=ndl.r)update(pos,x,now<<1);
    else update(pos,x,now<<1|1);
    nd.mx=add(ndl.mx,ndr.mx);
  }
  pii query(int s,int t,int now=1){
    if(s<=nd.l&&t>=nd.r) return nd.mx;
    pii res=mp(INF,INF);
    if(s<=ndl.r) res=add(res,query(s,t,now<<1));
    if(t>ndl.r) res=add(res,query(s,t,now<<1|1));
    return res;
  }
}tree[11];
int main() {
  io>>n>>m;
  rep(i,1,n){
    int x,y;io>>y;x=y;
    rep(j,1,10){
      if(x%10) a[i][j]=y;
      else a[i][j]=INF;
      x/=10;
    }
  }
  rep(i,1,10) tree[i].maketree(1,n,i);
  while(m--){
    int a,b,c;
    io>>a>>b>>c;
    if(a==1) {
      int d=c;
      rep(i,1,10){
        if(d%10) tree[i].update(b,c);
        else tree[i].update(b,INF);
        d/=10;
      }
    }else {
      int ans=2*INF;
      rep(i,1,10){
        pii res=tree[i].query(b,c);
        if(res.se!=INF) ans=min(ans,res.fi+res.se);
      }
      if(ans>=2*INF) ans=-1;
      printf("%d\n",ans);
    }
  }
}

 

posted @ 2019-09-06 03:51  nervending  阅读(350)  评论(0编辑  收藏  举报