J

题目链接: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
");
 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
",ans);
122         }
123     }
124     }
125     return 0;
126 }
原文地址:https://www.cnblogs.com/letlifestop/p/10419419.html