标签:scanf sync 区间 return ack str iter opera --
https://codeforc.es/contest/1217/problem/E
建立9棵数位线段树维护区间最小值和次小值,建议用struct建树方便进行区间合并
1 #define bug(x) cout<<#x<<" is "<<x<<endl 2 #define IO std::ios::sync_with_stdio(0) 3 #include <bits/stdc++.h> 4 #define iter ::iterator 5 #define pa pair<int,int> 6 using namespace std; 7 #define ll long long 8 #define mk make_pair 9 #define pb push_back 10 #define se second 11 #define fi first 12 #define ls o<<1 13 #define rs o<<1|1 14 ll mod=998244353; 15 const int N=2e5+5,h=2e9+5; 16 int n,q; 17 struct node{ 18 int mi[10]; 19 int mmi[10]; 20 node operator +(const node &t)const{ 21 node tmp; 22 for(int i=0;i<9;i++){ 23 tmp.mi[i]=min(mi[i],t.mi[i]); 24 25 if(mi[i]<t.mi[i]){ 26 tmp.mmi[i]=min(mmi[i],t.mi[i]); 27 } 28 else{ 29 tmp.mmi[i]=min(mi[i],t.mmi[i]); 30 } 31 } 32 return tmp; 33 } 34 }a[N*4]; 35 void up(int o,int l,int r,int k,int v){ 36 if(l==r){ 37 for(int i=0;i<9;i++){ 38 a[o].mi[i]=a[o].mmi[i]=h; 39 } 40 int t=v; 41 for(int i=0;i<9;i++){ 42 int x=t%10; 43 if(x){ 44 a[o].mi[i]=min(a[o].mi[i],v); 45 } 46 t/=10; 47 } 48 return; 49 } 50 int m=(l+r)/2; 51 if(k<=m)up(ls,l,m,k,v); 52 else up(rs,m+1,r,k,v); 53 a[o]=a[ls]+a[rs]; 54 } 55 node qu(int o,int l,int r,int ql,int qr){ 56 if(l>=ql&&r<=qr){ 57 return a[o]; 58 } 59 int m=(l+r)/2; 60 node res; 61 for(int i=0;i<9;i++){ 62 res.mi[i]=res.mmi[i]=h; 63 } 64 if(ql<=m)res=res+qu(ls,l,m,ql,qr); 65 if(qr>m)res=res+qu(rs,m+1,r,ql,qr); 66 return res; 67 } 68 int main(){ 69 scanf("%d%d",&n,&q); 70 for(int i=1;i<=n;i++){ 71 int x; 72 scanf("%d",&x); 73 up(1,1,n,i,x); 74 } 75 while(q--){ 76 int t,x,y; 77 scanf("%d%d%d",&t,&x,&y); 78 if(t==1)up(1,1,n,x,y); 79 else{ 80 node res=qu(1,1,n,x,y); 81 ll ans=h; 82 for(int i=0;i<9;i++){ 83 ans=min(ans,1ll*res.mi[i]+res.mmi[i]); 84 } 85 if(ans==h)ans=-1; 86 printf("%d\n",ans); 87 } 88 } 89 }
Educational Codeforces Round 72 (Rated for Div. 2)E. Sum Queries?(线段树区间合并)
标签:scanf sync 区间 return ack str iter opera --
原文地址:https://www.cnblogs.com/ccsu-kid/p/11488573.html