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