cf 1217E Sum Queries?
http://codeforces.com/problemset/problem/1217/E
这题的思路是:
1.首先不能有进位
2.由于要求和最小,所以我们只要选择两个数就可以了。
1 #include<bits/stdc++.h> 2 using namespace std; 3 int const N=200000+10; 4 int const inf=1e9+10; 5 #define lc (x<<1) 6 #define rc (x<<1|1) 7 #define mid (l+r)/2 8 struct node{ 9 int v1[10],v2[10]; 10 }t[N<<2]; 11 int a[N],n,m; 12 void pushup(int x){ 13 for(int i=1;i<=9;i++){ 14 t[x].v1[i]=min(t[lc].v1[i],t[rc].v1[i] ); 15 if(t[x].v1[i]==t[lc].v1[i]) 16 t[x].v2[i]=min(t[lc].v2[i],t[rc].v1[i]); 17 else 18 t[x].v2[i]=min(t[lc].v1[i],t[rc].v2[i]); 19 } 20 } 21 void build(int x,int l,int r){ 22 if(l==r){ 23 int p=1; 24 for(int i=1;i<=9;i++){ 25 int v=a[l]/p%10; 26 t[x].v1[i]=inf; t[x].v2[i]=inf; 27 if(v) t[x].v1[i]=a[l]; 28 p=p*10; 29 } 30 return ; 31 } 32 build(lc,l,mid); 33 build(rc,mid+1,r); 34 pushup(x); 35 } 36 void insert(int x,int l,int r,int p,int v){ 37 if(l==r){ 38 int p=1; 39 for(int i=1;i<=9;i++){ 40 int c=v/p%10; 41 t[x].v1[i]=t[x].v2[i]=inf; 42 if(c) t[x].v1[i]=v; 43 p=p*10; 44 } 45 return ; 46 } 47 if(p<=mid) insert(lc,l,mid,p,v); 48 else insert(rc,mid+1,r,p,v); 49 pushup(x); 50 } 51 node query(int x,int l,int r,int ll,int rr){ 52 if(ll<=l && r<=rr){ 53 return t[x]; 54 } 55 node t1,t2,ret; 56 for(int i=1;i<=9;i++) t1.v1[i]=t1.v2[i]=t2.v1[i]=t2.v2[i]=inf; 57 if(ll<=mid) t1=query(lc,l,mid,ll,rr); 58 if(rr>mid) t2=query(rc,mid+1,r,ll,rr); 59 for(int i=1;i<=9;i++){ 60 ret.v1[i]=min(t1.v1[i],t2.v1[i]); 61 if(ret.v1[i]==t1.v1[i]) 62 ret.v2[i]=min(t1.v2[i],t2.v1[i]); 63 else 64 ret.v2[i]=min(t1.v1[i],t2.v2[i]); 65 } 66 return ret; 67 } 68 int main(){ 69 scanf("%d%d",&n,&m); 70 for(int i=1;i<=n;i++) 71 scanf("%d",&a[i]); 72 build(1,1,n); 73 while (m--){ 74 int opt,x,y; 75 scanf("%d%d%d",&opt,&x,&y); 76 if(opt==1){ 77 insert(1,1,n,x,y) ; 78 }else { 79 node t=query(1,1,n,x,y); 80 int ans=2*inf; 81 for(int i=1;i<=9;i++){ 82 if(t.v1[i]!=inf && t.v2[i]!=inf) 83 ans=min(ans,t.v1[i]+t.v2[i]); 84 } 85 if(ans>=2*inf) ans=-1; 86 printf("%d\n",ans); 87 } 88 } 89 return 0; 90 }