J - Joseph and Tests Gym - 102020J (二分+线段树)
题目链接:https://cn.vjudge.net/contest/283920#problem/J
题目大意:首先给你n个门的高度,然后q次询问,每一次询问包括两种操作,第一种操作是将当前的门的高度提高到某一个值,第二种操作是给你一个起点,以及最大的跨越高度d,问你最远能走到哪里(如果能从a到达b则说明|Ha-Hb|<=d)。
具体思路:用线段树维护每一个区间的最大值,对于操作1就是单点修改了,对于操作二的话,用二分+线段树的方法查询最远能到达的地方就可以了。
AC代码:
1 #include<iostream> 2 #include<stack> 3 #include<cstring> 4 #include<iomanip> 5 #include<stdio.h> 6 #include<algorithm> 7 #include<cmath> 8 using namespace std; 9 # define ll long long 10 # define lson l,m,rt<<1 11 # define rson m+1,r,rt<<1|1 12 const int maxn = 2e5+100; 13 int tree[maxn<<2],a[maxn]; 14 int maxx; 15 void up(int rt) 16 { 17 tree[rt]=max(tree[rt<<1],tree[rt<<1|1]); 18 } 19 void buildtree(int l,int r,int rt) 20 { 21 if(l==r) 22 { 23 tree[rt]=abs(a[l]-a[l+1]); 24 return ; 25 } 26 int m=(l+r)>>1; 27 buildtree(lson); 28 buildtree(rson); 29 up(rt); 30 } 31 void update(int l,int r,int rt,int pos) 32 { 33 if(l==r) 34 { 35 tree[rt]=abs(a[l+1]-a[l]); 36 return ; 37 } 38 int m=(l+r)>>1; 39 if(pos<=m) 40 update(lson,pos); 41 else 42 update(rson,pos); 43 up(rt); 44 } 45 void query(int l,int r,int rt,int L,int R) 46 { 47 if(L<=l&&R>=r) 48 { 49 maxx=max(maxx,tree[rt]); 50 return ; 51 } 52 int m=(l+r)>>1; 53 if(L<=m) 54 query(lson,L,R); 55 if(R>m) 56 query(rson,L,R); 57 up(rt); 58 } 59 int Find(int n,int t2,int t3) 60 { 61 int l=t2,r=n; 62 int ans=n+1; 63 while(l<=r) 64 { 65 int mid=(l+r)>>1; 66 maxx=0; 67 query(1,n,1,l,mid); 68 // cout<<l<<" "<<r<<" "<<maxx<<" "<<t3<<endl; 69 if(maxx<=t3) 70 { 71 l=mid+1; 72 } 73 else 74 { 75 ans=mid; 76 r=mid-1; 77 } 78 } 79 return ans; 80 } 81 int main() 82 { 83 int n; 84 scanf("%d",&n); 85 for(int i=1; i<=n; i++) 86 { 87 scanf("%d",&a[i]); 88 } 89 int q,t1,t2,t3; 90 if(n==1){ 91 scanf("%d",&q); 92 while(q--){ 93 scanf("%d %d %d",&t1,&t2,&t3); 94 if(t1==1){ 95 a[t2]=t3; 96 } 97 else if(t1==2){ 98 printf("1\n"); 99 } 100 } 101 } 102 else{ 103 buildtree(1,n-1,1); 104 105 scanf("%d",&q); 106 while(q--) 107 { 108 scanf("%d %d %d",&t1,&t2,&t3); 109 // cout<<t1<<" "<<t2<<" "<<t3<<endl; 110 if(t1==1) 111 { 112 a[t2]=t3; 113 if(t2-1>0) 114 update(1,n-1,1,t2-1); 115 if(t2<=n-1) 116 update(1,n-1,1,t2); 117 } 118 else if(t1==2) 119 { 120 int ans=Find(n-1,t2,t3); 121 printf("%d\n",ans); 122 } 123 } 124 } 125 return 0; 126 }