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