每日一题 day28 打卡
Analysis
这道题用线段树维护区间最小值很简单,因为没有修改所以连lazy_tag都不用,但是这道题可以用树状数组维护区间最小值,非常骚气。
线段树代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define int long long 7 #define maxn 1000000+10 8 using namespace std; 9 inline int read() 10 { 11 int x=0; 12 bool f=1; 13 char c=getchar(); 14 for(; !isdigit(c); c=getchar()) if(c=='-') f=0; 15 for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0'; 16 if(f) return x; 17 return 0-x; 18 } 19 inline void write(int x) 20 { 21 if(x<0){putchar('-');x=-x;} 22 if(x>9)write(x/10); 23 putchar(x%10+'0'); 24 } 25 int m,n; 26 int a[maxn]; 27 struct Segment_tree 28 { 29 struct Segment_tree_node 30 { 31 int l,r,val; 32 }node[maxn*4]; 33 int n; 34 inline int size() {return n;} 35 inline int left_s(int x) {return (x<<1);} 36 inline int right_s(int x) {return ((x<<1)|1);} 37 inline void init(int l,int r) 38 { 39 n=r-l+1; 40 node[1].l=1; 41 node[1].r=n; 42 build(1); 43 } 44 inline void push_up(int x) 45 { 46 node[x].val=min(node[left_s(x)].val,node[right_s(x)].val); 47 } 48 inline void build(int x) 49 { 50 if(node[x].l==node[x].r) 51 { 52 node[x].val=a[node[x].l]; 53 return; 54 } 55 int mid=(node[x].l+node[x].r)>>1; 56 node[left_s(x)].l=node[x].l; 57 node[left_s(x)].r=mid; 58 build(left_s(x)); 59 node[right_s(x)].l=mid+1; 60 node[right_s(x)].r=node[x].r; 61 build(right_s(x)); 62 push_up(x); 63 } 64 inline int query(int x,int l,int r) 65 { 66 if(node[x].l==l&&node[x].r==r) 67 { 68 return node[x].val; 69 } 70 int mid=(node[x].l+node[x].r)>>1; 71 if(r<=mid) return query(left_s(x),l,r); 72 if(l>mid) return query(right_s(x),l,r); 73 return min(query(left_s(x),l,mid),query(right_s(x),mid+1,r)); 74 } 75 }t; 76 signed main() 77 { 78 m=read();n=read(); 79 for(int i=1;i<=m;i++) a[i]=read(); 80 t.init(1,m); 81 for(int i=1;i<=n;i++) 82 { 83 int x=read(),y=read(); 84 int ans=t.query(1,x,y); 85 write(ans); 86 printf(" "); 87 } 88 return 0; 89 }
树状数组代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define int long long 7 #define maxn 1000000+10 8 #define INF 2147483647 9 using namespace std; 10 inline int read() 11 { 12 int x=0; 13 bool f=1; 14 char c=getchar(); 15 for(; !isdigit(c); c=getchar()) if(c=='-') f=0; 16 for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0'; 17 if(f) return x; 18 return 0-x; 19 } 20 inline void write(int x) 21 { 22 if(x<0){putchar('-');x=-x;} 23 if(x>9)write(x/10); 24 putchar(x%10+'0'); 25 } 26 int m,n; 27 int a[maxn]; 28 int tree[maxn]; 29 inline int lowbit(int num) 30 { 31 return num&(-num); 32 } 33 inline void update(int s,int num) 34 { 35 int i=s; 36 while(i<=m) 37 { 38 if(tree[i]>num) 39 tree[i]=num; 40 else return; 41 i+=lowbit(i); 42 } 43 } 44 inline int query(int l,int r) 45 { 46 int res=INF,i=r; 47 while(i>=l) 48 { 49 if(i-lowbit(i)>l) 50 { 51 res=min(res,tree[i]); 52 i-=lowbit(i); 53 } 54 else 55 { 56 res=min(res,a[i]); 57 --i; 58 } 59 } 60 return res; 61 } 62 signed main() 63 { 64 memset(tree,127,sizeof(tree)); 65 m=read();n=read(); 66 for(int i=1;i<=m;i++) 67 { 68 a[i]=read(); 69 update(i,a[i]); 70 } 71 for(int i=1;i<=n;i++) 72 { 73 int x=read(),y=read(); 74 int ans=query(x,y); 75 write(ans); 76 printf(" "); 77 } 78 return 0; 79 }
请各位大佬斧正(反正我不认识斧正是什么意思)