建议先弄懂
    
     
      
       T 
2
        T2
      
      
       
        
        
        
         T
        
        
         2
        
       
      
     
    
    ,考虑使用单调栈+线段树/树状数组在固定右端点的情况下维护任意一个左端点到右端点的区间最值。
    
    
     代码风格不是平常的风格,平常代码一行只写一句,非常长所以放上来的时候
    
   
    
    
    
     T0:Edu124 E. Sum of Matchings
    
   
上课前讲的一道近期cf题目 待补。
然后上课刚开始,dls大致介绍了一下树状数组上二分,待补。
    
    
    
     T1:abc234_g Divide a Sequence
    
   
    这道题的大致题意是,给定一个长为
    
     
      
       n 
        n
      
      
       
        
        
        
         n
        
       
      
     
    
    的数组,我们可以对他进行一个
    
     划分
    
    ,每次划分的
    
     
      
       v 
a
l
u
e
s
        values
      
      
       
        
        
        
         v
        
        
         a
        
        
         l
        
        
         u
        
        
         e
        
        
         s
        
       
      
     
    
    是对所有部分的(最大值-最小值)进行累积。求所有划分的
    
     
      
       v 
a
l
u
e
s
        values
      
      
       
        
        
        
         v
        
        
         a
        
        
         l
        
        
         u
        
        
         e
        
        
         s
        
       
      
     
    
    的累和。
   
    
     划分:在不删除、移动数组种任何元素的情况下,将数组分割成若干子数组如{[1,2,3]}可以划分成{[1],[2,3]}或{[1],[2],[3]}等
    
   
    大致思路:
    
     容易
    
    得到
    
    
     
      
       f 
(
i
)
=
∑
j
=
0
i
−
2
f
(
j
)
∗
m
a
x
(
a
[
j
+
1
]
,
.
.
,
a
[
i
]
)
−
∑
j
=
0
i
−
2
f
(
j
)
∗
m
i
n
(
a
[
j
+
1
]
,
.
.
.
,
a
[
i
]
)
        f(i)=\sum_{j=0}^{i-2}f(j)*max(a[j+1],..,a[i])-\sum_{j=0}^{i-2}f(j)*min(a[j+1],…,a[i])
      
      
       
        
        
        
         f
        
        
         (
        
        
         i
        
        
         )
        
        
        
        
         =
        
        
        
       
       
        
        
        
         
          ∑
         
         
          
           
            
             
              
              
              
               
                
                 j
                
                
                 =
                
                
                 0
                
               
              
             
             
              
              
              
               
                
                 i
                
                
                 −
                
                
                 2
                
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
        
        
         f
        
        
         (
        
        
         j
        
        
         )
        
        
        
        
         ∗
        
        
        
       
       
        
        
        
         m
        
        
         a
        
        
         x
        
        
         (
        
        
         a
        
        
         [
        
        
         j
        
        
        
        
         +
        
        
        
       
       
        
        
        
         1
        
        
         ]
        
        
         ,
        
        
        
        
         .
        
        
         .
        
        
         ,
        
        
        
        
         a
        
        
         [
        
        
         i
        
        
         ]
        
        
         )
        
        
        
        
         −
        
        
        
       
       
        
        
        
         
          ∑
         
         
          
           
            
             
              
              
              
               
                
                 j
                
                
                 =
                
                
                 0
                
               
              
             
             
              
              
              
               
                
                 i
                
                
                 −
                
                
                 2
                
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
        
        
         f
        
        
         (
        
        
         j
        
        
         )
        
        
        
        
         ∗
        
        
        
       
       
        
        
        
         m
        
        
         i
        
        
         n
        
        
         (
        
        
         a
        
        
         [
        
        
         j
        
        
        
        
         +
        
        
        
       
       
        
        
        
         1
        
        
         ]
        
        
         ,
        
        
        
        
         .
        
        
         .
        
        
         .
        
        
         ,
        
        
        
        
         a
        
        
         [
        
        
         i
        
        
         ]
        
        
         )
        
       
      
     
    
    
    然后考虑维护(
    
     
      
       m 
i
n
        min
      
      
       
        
        
        
         m
        
        
         i
        
        
         n
        
       
      
     
    
    维护和
    
     
      
       m 
a
x
        max
      
      
       
        
        
        
         m
        
        
         a
        
        
         x
        
       
      
     
    
    维护相同)
    
    
     
      
       ∑ 
j
=
0
i
−
2
f
(
j
)
∗
m
a
x
(
a
[
j
+
1
]
,
.
.
,
a
[
i
]
)
        \sum_{j=0}^{i-2}f(j)*max(a[j+1],..,a[i])
      
      
       
        
        
        
         
          ∑
         
         
          
           
            
             
              
              
              
               
                
                 j
                
                
                 =
                
                
                 0
                
               
              
             
             
              
              
              
               
                
                 i
                
                
                 −
                
                
                 2
                
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
        
        
         f
        
        
         (
        
        
         j
        
        
         )
        
        
        
        
         ∗
        
        
        
       
       
        
        
        
         m
        
        
         a
        
        
         x
        
        
         (
        
        
         a
        
        
         [
        
        
         j
        
        
        
        
         +
        
        
        
       
       
        
        
        
         1
        
        
         ]
        
        
         ,
        
        
        
        
         .
        
        
         .
        
        
         ,
        
        
        
        
         a
        
        
         [
        
        
         i
        
        
         ]
        
        
         )
        
       
      
     
    
    
    这里的
    
     
      
       m 
a
x
        max
      
      
       
        
        
        
         m
        
        
         a
        
        
         x
        
       
      
     
    
    可以通过单调栈维护
   
    
     AC code:
    
   
#include <bits/stdc++.h>
#define mod 998244353
#define int long long
#define lowbit(x) (x&(-x))
using namespace std;
int n,k,m,cnt;
int a[300005];
int dp[300005];
stack <int>s1,s2;
int tr[300005];
void add(int x,int k){for(int i=x;i<=n;i+=lowbit(i)) (tr[i]+=k)%=mod;}
int qr(int x,int res=0){
    for(int i=x;i>0;i-=lowbit(i)) (res+=tr[i])%=mod;
    if(x>=0)(res+=1)%=mod;
    return res;
}
int ask(int l,int r){return (mod+qr(r)-qr(l-1))%mod;}
void solve(){
    cin>>n;dp[0]=1;
    for(int i=1;i<=n;i++){cin>>a[i];}
    s1.push(0);s2.push(0);
    int maxsum=0,minsum=0;
    for(int i=1;i<=n;i++){
        while(s1.top()!=0&&a[s1.top()]<=a[i]){
            int u=s1.top();s1.pop();
            int dx=ask(s1.top(),u-1);
            maxsum=(maxsum-dx*a[u]%mod+mod)%mod;
        }
        maxsum=(maxsum+ask(s1.top(),i)*a[i]%mod)%mod;
        s1.push(i);
        while(s2.top()!=0&&a[s2.top()]>=a[i]){
            int u=s2.top();s2.pop();
            int dx=ask(s2.top(),u-1);
            minsum=(minsum-dx*a[u]%mod+mod)%mod;
        }
        minsum=(minsum+ask(s2.top(),i)*a[i]%mod+mod)%mod;
        s2.push(i);
        dp[i]=(maxsum-minsum+mod)%mod;
        add(i,dp[i]);
    }
    cout<<dp[n]<<endl;
}
signed main(){
    ios::sync_with_stdio(false);cin.tie(0);
    int t=1;
    while (t--)
        solve();
}
    
    
    
     T2:CF1635F Closest Pair
    
   
    题目大意:给定
    
     
      
       n 
        n
      
      
       
        
        
        
         n
        
       
      
     
    
    个点,每个点有一个
    
     
      
       x 
i
,
w
i
        x_i,w_i
      
      
       
        
        
        
         
          x
         
         
          
           
            
             
              
              
              
               
                i
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
         ,
        
        
        
        
         
          w
         
         
          
           
            
             
              
              
              
               
                i
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
       
      
     
    
    (每个点按照
    
     
      
       x 
i
        x_i
      
      
       
        
        
        
         
          x
         
         
          
           
            
             
              
              
              
               
                i
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
       
      
     
    
    从小到大给出)。对于任意两点,他们的
    
     
      
       v 
a
l
=
∣
x
i
−
x
j
∣
∗
(
w
i
+
w
j
)
        val=\vert x_i-x_j \vert *(w_i+w_j)
      
      
       
        
        
        
         v
        
        
         a
        
        
         l
        
        
        
        
         =
        
        
        
       
       
        
        
        
         ∣
        
        
         
          x
         
         
          
           
            
             
              
              
              
               
                i
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
        
        
         −
        
        
        
       
       
        
        
        
         
          x
         
         
          
           
            
             
              
              
              
               
                j
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
         ∣
        
        
        
        
         ∗
        
        
        
       
       
        
        
        
         (
        
        
         
          w
         
         
          
           
            
             
              
              
              
               
                i
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
        
        
         +
        
        
        
       
       
        
        
        
         
          w
         
         
          
           
            
             
              
              
              
               
                j
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
         )
        
       
      
     
    
    。
    
    给定
    
     
      
       n 
        n
      
      
       
        
        
        
         n
        
       
      
     
    
    个询问,求每个询问给定的
    
     
      
       [ 
l
i
,
r
i
]
        [l_i,r_i]
      
      
       
        
        
        
         [
        
        
         
          l
         
         
          
           
            
             
              
              
              
               
                i
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
         ,
        
        
        
        
         
          r
         
         
          
           
            
             
              
              
              
               
                i
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
         ]
        
       
      
     
    
    中,
    
     
      
       v 
a
l
        val
      
      
       
        
        
        
         v
        
        
         a
        
        
         l
        
       
      
     
    
    最小的点对
   
大致思路 :
1.使用单调栈得出所有可以成为答案的点对,且需要证明能够成为答案的点对至多
2n
2n
2
n
对
2.考虑将所有提问离线按照右端点排序,并用树状数组/线段树维护区间最小值
    ①证明过程:在所有点按照
    
     
      
       x 
        x
      
      
       
        
        
        
         x
        
       
      
     
    
    坐标排序的情况下,对于两个不同点
    
     
      
       ( 
x
1
,
w
1
)
,
(
x
2
,
w
2
)
        (x_1,w_1),(x_2,w_2)
      
      
       
        
        
        
         (
        
        
         
          x
         
         
          
           
            
             
              
              
              
               
                1
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
         ,
        
        
        
        
         
          w
         
         
          
           
            
             
              
              
              
               
                1
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
         )
        
        
         ,
        
        
        
        
         (
        
        
         
          x
         
         
          
           
            
             
              
              
              
               
                2
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
         ,
        
        
        
        
         
          w
         
         
          
           
            
             
              
              
              
               
                2
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
         )
        
       
      
     
    
    ,若
    
     
      
       x 
1
<
x
2
&
&
w
1
≥
w
2
        x_1<x_2 \&\& w_1\geq w_2
      
      
       
        
        
        
         
          x
         
         
          
           
            
             
              
              
              
               
                1
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
        
        
         <
        
        
        
       
       
        
        
        
         
          x
         
         
          
           
            
             
              
              
              
               
                2
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
         &
        
        
         &
        
        
         
          w
         
         
          
           
            
             
              
              
              
               
                1
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
        
        
         ≥
        
        
        
       
       
        
        
        
         
          w
         
         
          
           
            
             
              
              
              
               
                2
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
       
      
     
    
    ,那么显然
    
     
      
       ( 
x
1
,
w
1
)
        (x_1,w_1)
      
      
       
        
        
        
         (
        
        
         
          x
         
         
          
           
            
             
              
              
              
               
                1
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
         ,
        
        
        
        
         
          w
         
         
          
           
            
             
              
              
              
               
                1
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
         )
        
       
      
     
    
    与
    
     
      
       ( 
x
2
,
w
2
)
        (x_2,w_2)
      
      
       
        
        
        
         (
        
        
         
          x
         
         
          
           
            
             
              
              
              
               
                2
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
         ,
        
        
        
        
         
          w
         
         
          
           
            
             
              
              
              
               
                2
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
         )
        
       
      
     
    
    右侧任意一点成为答案的时候,选择
    
     
      
       ( 
x
2
,
w
2
)
        (x_2,w_2)
      
      
       
        
        
        
         (
        
        
         
          x
         
         
          
           
            
             
              
              
              
               
                2
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
         ,
        
        
        
        
         
          w
         
         
          
           
            
             
              
              
              
               
                2
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
         )
        
       
      
     
    
    一定更优。上述的所有点显然是可以使用一个栈内递增的单调栈维护。在每次对栈操作时(无论是弹出还是插入前),栈顶段与当前端点一定是一个可能成为答案的点对。单调栈操作至多操作
    
     
      
       2 
∗
n
−
2
        2*n-2
      
      
       
        
        
        
         2
        
        
        
        
         ∗
        
        
        
       
       
        
        
        
         n
        
        
        
        
         −
        
        
        
       
       
        
        
        
         2
        
       
      
     
    
    次,所以能够成为答案的点对至多
    
     
      
       2 
∗
n
−
2
        2*n-2
      
      
       
        
        
        
         2
        
        
        
        
         ∗
        
        
        
       
       
        
        
        
         n
        
        
        
        
         −
        
        
        
       
       
        
        
        
         2
        
       
      
     
    
    对。
   
    
     AC code
    
   
#include <bits/stdc++.h>
#define mod 998244353
#define int long long
#define endl '\n'
#define lowbit(x) (x&(-x))
#define mid ((l+r)>>1)
#define ls rt<<1
#define rs rt<<1|1
#define lson ls,l,mid
#define rson rs,mid+1,r
using namespace std;
int n,l,r,k,m,cnt,q;
stack <int>s;
int tr[1200005];
int fk[300005];
struct node {
    int l,r,id;
    bool operator <(const node &t)const{return r<t.r||r==t.r&&l<t.l;}
}ans[600005],a[300005],ask[300005];
void push_up(int rt){tr[rt]=min(tr[rt<<1],tr[rt<<1|1]);}
void build(int rt,int l,int r){
	if(l==r){tr[rt]=4000000000000000001;return;}
	build(lson);build(rson);
	push_up(rt);
}
void update(int rt,int l,int r,int ql,int qr,int k){
	if(l>=ql&&r<=qr){tr[rt]=min(tr[rt],k);return;}
	if(mid>=ql)update(lson,ql,qr,k);
	if(mid<qr)update(rson,ql,qr,k);
	push_up(rt);
}
int query(int rt,int l,int r,int ql,int qr,int res=4000000000000000001){
	if(l>=ql&&r<=qr) return tr[rt];
	if(mid>=ql)res=min(res,query(lson,ql,qr));
	if(mid<qr)res=min(res,query(rson,ql,qr));
	return res;
}
int get(node t){int u=t.l,v=t.r;return abs(a[v].l-a[u].l)*(a[v].r+a[u].r);}
void solve(){
    cin>>n>>q;
    build(1,1,n);
    for(int i=1;i<=n;i++){
        cin>>a[i].l>>a[i].r;
        while(!s.empty()&&a[s.top()].r>=a[i].r){
            ans[++cnt]={s.top(),i,0};
            s.pop();
        }
        if(!s.empty()) ans[++cnt]={s.top(),i,0};
        s.push(i);
    }
    for(int i=1;i<=q;i++){cin>>ask[i].l>>ask[i].r;ask[i].id=i;}
    sort(ask+1,ask+1+q);
    for(int i=1,j=1;j<=q&&i<=cnt+1;i++){
        while(j<=q&&(ask[j].r<ans[i].r||i==cnt+1)){
            fk[ask[j].id]=query(1,1,n,ask[j].l,n);
            j++;
        }
        if(i==cnt+1)break;
        update(1,1,n,ans[i].l,ans[i].l,get(ans[i]));
    }
    for(int i=1;i<=q;i++){cout<<fk[i]<<endl;}
}
 
signed main(){
    ios::sync_with_stdio(false);cin.tie(0);
    int t=1;
    while (t--)
        solve();
}
    
    
    
     T3:洛谷P1972 HH的项链
    
   
题目大意:不重要,自己点进去看
    大致思路:
    
     
      
       T 
2
        T2
      
      
       
        
        
        
         T
        
        
         2
        
       
      
     
    
    中思路
    
     
      
       2 
        2
      
      
       
        
        
        
         2
        
       
      
     
    
    的模板,离线询问后用树状数组/线段树维护区间性质。
   
    
     AC code
    
   
#include <bits/stdc++.h>
#define mod 998244353
#define int long long
#define endl '\n'
#define lowbit(x) (x&(-x))
using namespace std;
int n,l,r,k,m,cnt;
int a[1000005],last[1000005];
stack <int>s1,s2;
int tr[1000005];
int fk[1000005];
void add(int x,int k){for(int i=x;i<=n;i+=lowbit(i)) tr[i]+=k;}
int qr(int x,int res=0){for(int i=x;i>0;i-=lowbit(i)) res+=tr[i];return res;}
int ask(int l,int r){return (mod+qr(r)-qr(l-1))%mod;}
struct node {
    int l,r,id;
    bool operator <(const node &t)const{return r<t.r||r==t.r&&l<t.l;}
}ans[1000005];
void solve(){
    cin>>n;for(int i=1;i<=n;i++){cin>>a[i];}
    cin>>m;for(int i=1;i<=m;i++){cin>>ans[i].l>>ans[i].r;ans[i].id=i;}
    sort(ans+1,ans+1+m);
    for(int i=1,j=1;j<=m&&i<=n;i++){
        add(i,1);
        if(last[a[i]]!=0){add(last[a[i]],-1);}
        last[a[i]]=i;
        while(j<=m&&ans[j].r==i){
            fk[ans[j].id]=ask(ans[j].l,ans[j].r);
            j++;
        }
    }
    for(int i=1;i<=m;i++){cout<<fk[i]<<endl;}
}
signed main(){
    ios::sync_with_stdio(false);cin.tie(0);
    int t=1;
    while (t--)
        solve();
}
    
    
    
     T4:CF526F Pudding Monsters
    
   
    大致题意:给定一个
    
     
      
       n 
×
n
        n \times n
      
      
       
        
        
        
         n
        
        
        
        
         ×
        
        
        
       
       
        
        
        
         n
        
       
      
     
    
    的棋盘,其中有
    
     
      
       n 
        n
      
      
       
        
        
        
         n
        
       
      
     
    
    个棋子,每行每列恰好有一个棋子。
   
    求有多少个
    
     
      
       k 
×
k
        k \times k
      
      
       
        
        
        
         k
        
        
        
        
         ×
        
        
        
       
       
        
        
        
         k
        
       
      
     
    
    的子棋盘中恰好有
    
     
      
       k 
        k
      
      
       
        
        
        
         k
        
       
      
     
    
    个棋子。
   
    题解:首先因为题目保证每行每列都有一个棋子,所以我们可以将点对
    
     降维
    
    存储为
    
     
      
       a 
[
x
]
=
y
        a[x]=y
      
      
       
        
        
        
         a
        
        
         [
        
        
         x
        
        
         ]
        
        
        
        
         =
        
        
        
       
       
        
        
        
         y
        
       
      
     
    
    。
    
    
     容易想到
    
    对于任意一个
    
     
      
       [ 
l
,
r
]
        [l,r]
      
      
       
        
        
        
         [
        
        
         l
        
        
         ,
        
        
        
        
         r
        
        
         ]
        
       
      
     
    
    区间内,假设区间最大值为
    
     
      
       m 
a
x
n
        maxn
      
      
       
        
        
        
         m
        
        
         a
        
        
         x
        
        
         n
        
       
      
     
    
    ,区间最小值是
    
     
      
       m 
i
n
n
        minn
      
      
       
        
        
        
         m
        
        
         i
        
        
         n
        
        
         n
        
       
      
     
    
    ,那么对于这个区间,如果刚好每行每列有一个棋子,则满足
    
     
      
       m 
a
x
n
−
m
i
n
n
=
r
−
l
        maxn-minn=r-l
      
      
       
        
        
        
         m
        
        
         a
        
        
         x
        
        
         n
        
        
        
        
         −
        
        
        
       
       
        
        
        
         m
        
        
         i
        
        
         n
        
        
         n
        
        
        
        
         =
        
        
        
       
       
        
        
        
         r
        
        
        
        
         −
        
        
        
       
       
        
        
        
         l
        
       
      
     
    
    。将等式右边移到左边,变成
    
     
      
       ( 
m
a
x
n
−
m
i
n
n
)
−
(
r
−
l
)
=
0
        (maxn-minn)-(r-l)=0
      
      
       
        
        
        
         (
        
        
         m
        
        
         a
        
        
         x
        
        
         n
        
        
        
        
         −
        
        
        
       
       
        
        
        
         m
        
        
         i
        
        
         n
        
        
         n
        
        
         )
        
        
        
        
         −
        
        
        
       
       
        
        
        
         (
        
        
         r
        
        
        
        
         −
        
        
        
       
       
        
        
        
         l
        
        
         )
        
        
        
        
         =
        
        
        
       
       
        
        
        
         0
        
       
      
     
    
    。题目转变为,求满足以上等式的区间数量。
    
    
     考虑固定右端点
    
    ,当右端点固定为
    
     
      
       r 
        r
      
      
       
        
        
        
         r
        
       
      
     
    
    的时候,我们只需要判断左端点选择
    
     
      
       1 
        1
      
      
       
        
        
        
         1
        
       
      
     
    
    到
    
     
      
       r 
        r
      
      
       
        
        
        
         r
        
       
      
     
    
    时对应区间的性质,我们需要一个数据结构,保证维护每次的点
    
     
      
       l 
        l
      
      
       
        
        
        
         l
        
       
      
     
    
    到当前固定右端点的区间的性质。
    
    重看上述等式
    
     
      
       ( 
m
a
x
n
−
m
i
n
n
)
−
(
r
−
l
)
=
0
        (maxn-minn)-(r-l)=0
      
      
       
        
        
        
         (
        
        
         m
        
        
         a
        
        
         x
        
        
         n
        
        
        
        
         −
        
        
        
       
       
        
        
        
         m
        
        
         i
        
        
         n
        
        
         n
        
        
         )
        
        
        
        
         −
        
        
        
       
       
        
        
        
         (
        
        
         r
        
        
        
        
         −
        
        
        
       
       
        
        
        
         l
        
        
         )
        
        
        
        
         =
        
        
        
       
       
        
        
        
         0
        
       
      
     
    
    ,容易证明
    
     
      
       m 
a
x
n
−
m
i
n
n
≥
r
−
l
        maxn-minn \geq r-l
      
      
       
        
        
        
         m
        
        
         a
        
        
         x
        
        
         n
        
        
        
        
         −
        
        
        
       
       
        
        
        
         m
        
        
         i
        
        
         n
        
        
         n
        
        
        
        
         ≥
        
        
        
       
       
        
        
        
         r
        
        
        
        
         −
        
        
        
       
       
        
        
        
         l
        
       
      
     
    
    ,所以我们当等式等于
    
     
      
       0 
        0
      
      
       
        
        
        
         0
        
       
      
     
    
    时,即是区间最小值,所以我们只需要维护
    
     区间最小值且等于0的个数
    
    。
    
    考虑维护上述等式
    
     
      
       4 
        4
      
      
       
        
        
        
         4
        
       
      
     
    
    个变量
    
    1.
    
     
      
       r 
        r
      
      
       
        
        
        
         r
        
       
      
     
    
    ,当区间右端点
    
     
      
       r 
        r
      
      
       
        
        
        
         r
        
       
      
     
    
    变成
    
     
      
       r 
−
1
        r-1
      
      
       
        
        
        
         r
        
        
        
        
         −
        
        
        
       
       
        
        
        
         1
        
       
      
     
    
    时,所有的左区间对应的区间长度+1,我们只需要对线段树全部
    
     
      
       − 
1
        -1
      
      
       
        
        
        
         −
        
        
         1
        
       
      
     
    
    即可。
    
    2.
    
     
      
       l 
        l
      
      
       
        
        
        
         l
        
       
      
     
    
    ,显然,所有的
    
     
      
       l 
        l
      
      
       
        
        
        
         l
        
       
      
     
    
    都是在每个节点上都是一个常量,是不会变化的,我们在建立线段树的时候直接确定即可。
    
    3.
    
     
      
       m 
a
x
n
        maxn
      
      
       
        
        
        
         m
        
        
         a
        
        
         x
        
        
         n
        
       
      
     
    
    ,表示区间
    
     
      
       l 
        l
      
      
       
        
        
        
         l
        
       
      
     
    
    到
    
     
      
       r 
        r
      
      
       
        
        
        
         r
        
       
      
     
    
    的区间最大值,可以通过单调栈+线段树维护。
    
    4.
    
     
      
       m 
i
n
n
        minn
      
      
       
        
        
        
         m
        
        
         i
        
        
         n
        
        
         n
        
       
      
     
    
    ,同3。
    
    将上述操作实现之后在固定每个右端点,每次查
    
     
      
       [ 
1
,
r
]
        [1,r]
      
      
       
        
        
        
         [
        
        
         1
        
        
         ,
        
        
        
        
         r
        
        
         ]
        
       
      
     
    
    的区间最小值且等于
    
     
      
       0 
        0
      
      
       
        
        
        
         0
        
       
      
     
    
    的个数即可。
    
    复杂度
    
     
      
       O 
(
n
l
o
g
n
)
        O(nlogn)
      
      
       
        
        
        
         O
        
        
         (
        
        
         n
        
        
         l
        
        
         o
        
        
         g
        
        
         n
        
        
         )
        
       
      
     
    
    
    
     AC code
    
   
#include <bits/stdc++.h>
#define mod 998244353
#define int long long
#define endl '\n'
#define lowbit(x) (x&(-x))
#define mid ((l+r)>>1)
#define ls rt<<1
#define rs rt<<1|1
#define lson ls,l,mid
#define rson rs,mid+1,r
using namespace std;
const int N = 100005;
string yes="YES\n",no="NO\n";
int n,op,l,r,k,m,q,ans;
stack <int>s1,s2;
int a[300005];
int cnt[1200005],minx[1200005],tr[1200005],lazy[1200005];
void push_up(int rt){
    minx[rt]=min(minx[ls],minx[rs]);cnt[rt]=0;
    if(minx[rt]==minx[ls])cnt[rt]+=cnt[ls];
    if(minx[rt]==minx[rs])cnt[rt]+=cnt[rs];
}
void build(int rt,int l,int r){
	if(l==r){minx[rt]=l;cnt[rt]=1;return;}
	build(lson);build(rson);
	cnt[rt]=cnt[ls];minx[rt]=minx[ls];
}
void push_down(int rt){
    minx[ls]+=lazy[rt];minx[rs]+=lazy[rt];
    lazy[ls]+=lazy[rt];lazy[rs]+=lazy[rt];
    lazy[rt]=0;
}
void update(int rt,int l,int r,int ql,int qr,int k){
	if(l>=ql&&r<=qr){minx[rt]+=k;lazy[rt]+=k;return;}
    push_down(rt);
	if(mid>=ql)update(lson,ql,qr,k);
	if(mid<qr)update(rson,ql,qr,k);
	push_up(rt);
}
int query(int rt,int l,int r,int ql,int qr,int res=0){
	if(l>=ql&&r<=qr) return cnt[rt];
    push_down(rt);
	if(mid>=ql)res+=query(lson,ql,qr);
	if(mid<qr)res+=query(rson,ql,qr);
	return res;
}
void solve(){
    cin>>n;s1.push(0);s2.push(0);
    for(int i=1;i<=n;i++){int x,y;cin>>x>>y;a[x]=y;}
    build(1,1,n);
    for(int i=1;i<=n;i++){
        update(1,1,n,1,n,-1);
        while(s1.top()!=0&&a[s1.top()]<a[i]){
            int u=s1.top();s1.pop();
            update(1,1,n,s1.top()+1,u,a[i]-a[u]);
        }
        while(s2.top()!=0&&a[s2.top()]>a[i]){
            int u=s2.top();s2.pop();
            update(1,1,n,s2.top()+1,u,a[u]-a[i]);
        }
        s1.push(i);s2.push(i);
        ans+=query(1,1,n,1,i);
    }
    cout<<ans;
}
signed main(){
    int t=1;
    while (t--)
        solve();
}
    
    
    
     T5:CF765F Souvenirs
    
   
    题目大意:给定一个数组,
    
     
      
       q 
        q
      
      
       
        
        
        
         q
        
       
      
     
    
    次询问,每次问
    
     
      
       【 
l
i
,
r
i
】
        【l_i,r_i】
      
      
       
        
        
        
         【
        
        
         
          l
         
         
          
           
            
             
              
              
              
               
                i
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
         ,
        
        
        
        
         
          r
         
         
          
           
            
             
              
              
              
               
                i
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
         】
        
       
      
     
    
    之间相差最近两个数的差值。
    
    简要题解:仍然是首先离线询问,考虑维护每个
    
     
      
       l 
        l
      
      
       
        
        
        
         l
        
       
      
     
    
    到
    
     
      
       r 
        r
      
      
       
        
        
        
         r
        
       
      
     
    
    区间的对应的答案存储到
    
     
      
       l 
        l
      
      
       
        
        
        
         l
        
       
      
     
    
    上。
    
    权值线段树维护区间对应最大值(每次单点插入
    
     
      
       a 
[
i
]
        a[i]
      
      
       
        
        
        
         a
        
        
         [
        
        
         i
        
        
         ]
        
       
      
     
    
    处插入
    
     
      
       i 
        i
      
      
       
        
        
        
         i
        
       
      
     
    
    )
    
    线段树维护
    
     
      
       l 
        l
      
      
       
        
        
        
         l
        
       
      
     
    
    到对应区间的最小值。
    
    考虑对于大于
    
     
      
       a 
[
i
]
        a[i]
      
      
       
        
        
        
         a
        
        
         [
        
        
         i
        
        
         ]
        
       
      
     
    
    部分维护答案:
    
    首先在权值线段树中找到
    
     
      
       a 
[
i
]
        a[i]
      
      
       
        
        
        
         a
        
        
         [
        
        
         i
        
        
         ]
        
       
      
     
    
    到
    
     
      
       1 
e
9
        1e9
      
      
       
        
        
        
         1
        
        
         e
        
        
         9
        
       
      
     
    
    中最大的值,在线段树中对应位置更新为
    
     
      
       a 
[
u
]
−
a
[
i
]
        a[u]-a[i]
      
      
       
        
        
        
         a
        
        
         [
        
        
         u
        
        
         ]
        
        
        
        
         −
        
        
        
       
       
        
        
        
         a
        
        
         [
        
        
         i
        
        
         ]
        
       
      
     
    
    ,然后继续找到
    
     
      
       a 
[
i
]
        a[i]
      
      
       
        
        
        
         a
        
        
         [
        
        
         i
        
        
         ]
        
       
      
     
    
    到
    
     
      
       ( 
a
[
i
]
+
a
[
u
]
)
/
2
        (a[i]+a[u])/2
      
      
       
        
        
        
         (
        
        
         a
        
        
         [
        
        
         i
        
        
         ]
        
        
        
        
         +
        
        
        
       
       
        
        
        
         a
        
        
         [
        
        
         u
        
        
         ]
        
        
         )
        
        
         /
        
        
         2
        
       
      
     
    
    区间内最大值,进行同样操作,知道找不到值或
    
     
      
       a 
[
u
]
=
=
a
[
i
]
        a[u]==a[i]
      
      
       
        
        
        
         a
        
        
         [
        
        
         u
        
        
         ]
        
        
        
        
         =
        
       
       
        
        
        
         =
        
        
        
       
       
        
        
        
         a
        
        
         [
        
        
         i
        
        
         ]
        
       
      
     
    
    为止。
    
    对于小于
    
     
      
       a 
[
i
]
        a[i]
      
      
       
        
        
        
         a
        
        
         [
        
        
         i
        
        
         ]
        
       
      
     
    
    部分维护同上。
    
    复杂度
    
     
      
       O 
(
n
l
o
g
2
n
)
        O(nlog^2n)
      
      
       
        
        
        
         O
        
        
         (
        
        
         n
        
        
         l
        
        
         o
        
        
         
          g
         
         
          
           
            
             
              
              
              
               
                2
               
              
             
            
           
          
         
        
        
         n
        
        
         )
        
       
      
     
    
   
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define lowbit(x) (x&(-x))
#define mid ((l+r)>>1)
using namespace std;
const int N = 100005;
int n,l,r,k,m,q,x;
int a[100005],ans[300005];
int tr[4000005],ls[4000005],rs[4000005],root,cnt;
int c[400005];//命名后面带1的是线段树维护区间最小值
void push_up1(int rt){c[rt]=min(c[rt<<1],c[rt<<1|1]);}
void update1(int rt,int l,int r,int k,int x){
    if(l==r) {c[rt]=min(c[rt],x);return;}
    if(mid>=k)update1(rt<<1,l,mid,k,x);
	if(mid<k)update1(rt<<1|1,mid+1,r,k,x);
	push_up1(rt);
}
int query1(int rt,int l,int r,int ql,int qr,int res=1000000000){
    if(l>=ql&&r<=qr)return c[rt];
    if(mid>=ql)res=min(res,query1(rt<<1,l,mid,ql,qr));
    if(mid<qr)res=min(res,query1(rt<<1|1,mid+1,r,ql,qr));
    return res;
}
struct node{
    int l,r,id;
    bool operator < (const node &t) const{return r<t.r;}
}ri[300005];
void push_up(int rt){tr[rt]=max(tr[ls[rt]],tr[rs[rt]]);}//动态开点维护区间最大值
void update(int &rt,int l,int r,int k,int x){
    if(!rt) {rt=++cnt;} 
    if(l==r){tr[rt]=max(tr[rt],x);return;}
	if(mid>=k)update(ls[rt],l,mid,k,x);
	if(mid<k)update(rs[rt],mid+1,r,k,x);
	push_up(rt);
}
int query(int rt,int l,int r,int ql,int qr,int res=0){
	if(!rt||l>=ql&&r<=qr) return tr[rt];
	if(mid>=ql)res=max(res,query(ls[rt],l,mid,ql,qr));
	if(mid<qr)res=max(res,query(rs[rt],mid+1,r,ql,qr));
	return res;
}
void solve(){
    memset(c,0x3f,sizeof(c));
    cin>>n;for(int i=1;i<=n;i++){cin>>a[i];}
    cin>>m;for(int i=1;i<=m;i++){cin>>ri[i].l>>ri[i].r;ri[i].id=i;}
    sort(ri+1,ri+1+m);
    update(root,0,1000000000,a[1],1);
    for(int i=2,j=1;i<=n&&j<=m;i++){
        int u=query(root,0,1000000000,a[i],1000000000),v=query(root,0,1000000000,0,a[i]);
        while(u){  
            update1(1,1,n,u,a[u]-a[i]);
            if(a[u]==a[i])break;
            u=query(root,0,1000000000,a[i],(a[i]+a[u])/2);//往靠近a[i]方向取整所以向下取整
        }
        while(v){
            update1(1,1,n,v,a[i]-a[v]);
            if(a[v]==a[i])break;
            v=query(root,0,1000000000,(a[v]+a[i]+1)/2,a[i]);//往靠近a[i]方向取整所以向上取整
        }
        update(root,0,1000000000,a[i],i);
        while(j<=m&&ri[j].r==i){
            int cao=query1(1,1,n,ri[j].l,i);
            ans[ri[j].id]=cao;
            j++;
        }
    }
    for(int i=1;i<=m;i++){cout<<ans[i]<<endl;}
}
signed main(){
    int t=1;
    while (t--)
        solve();
}
    
    
    
     T6:CF438D The Child and Sequence
    
   
题目大意:给一个数组,支持区间取模,单点修改,查区间和。
    题目思路:首先对三个操作写一个暴力,区间求和与单点修改操作都是基本线段树操作,直接套板子即可。所以考虑区间取模。
    
    考虑一个简单的剪枝,假设输入的模数为
    
     
      
       k 
        k
      
      
       
        
        
        
         k
        
       
      
     
    
    ,对于区间内的所有点,只有大于
    
     
      
       k 
        k
      
      
       
        
        
        
         k
        
       
      
     
    
    的数会遭受修改,而所有比k小的数都是不变的,所以在线段树上,我们统计一个区间
    
     
      
       m 
a
x
        max
      
      
       
        
        
        
         m
        
        
         a
        
        
         x
        
       
      
     
    
    ,如果区间
    
     
      
       m 
a
x
<
k
        max<k
      
      
       
        
        
        
         m
        
        
         a
        
        
         x
        
        
        
        
         <
        
        
        
       
       
        
        
        
         k
        
       
      
     
    
    ,那么我们这一段区间内的所有数其实都不会发生改变,不需要
    
     
      
       u 
p
d
a
t
e
        update
      
      
       
        
        
        
         u
        
        
         p
        
        
         d
        
        
         a
        
        
         t
        
        
         e
        
       
      
     
    
    。
    
    这是一个非常暴力的写法,但是我们只需要增加一个这个判断即可通过这题。
    
    粗略证明:考虑到取模操作 ,容易证明在
    
     
      
       a 
≤
k
        a\leq k
      
      
       
        
        
        
         a
        
        
        
        
         ≤
        
        
        
       
       
        
        
        
         k
        
       
      
     
    
    的情况下
    
     
      
       a 
%
k
<
a
2
        a \% k < \frac a2
      
      
       
        
        
        
         a
        
        
         %
        
        
         k
        
        
        
        
         <
        
        
        
       
       
        
        
        
         
         
         
          
           
            
             
              
              
              
               
                2
               
              
             
             
              
              
              
              
             
             
              
              
              
               
                a
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
         
         
        
       
      
     
    
    (可以结合
    
     
      
       g 
c
d
        gcd
      
      
       
        
        
        
         g
        
        
         c
        
        
         d
        
       
      
     
    
    的复杂度证明莱思考),所以对任意一点,取模操作至多
    
     
      
       l 
o
g
        log
      
      
       
        
        
        
         l
        
        
         o
        
        
         g
        
       
      
     
    
    次,单点修改至多增加
    
     
      
       l 
o
g
        log
      
      
       
        
        
        
         l
        
        
         o
        
        
         g
        
       
      
     
    
    次操作,所以整体操作次数不会超过
    
     
      
       O 
(
n
l
o
o
g
n
)
        O(nloogn)
      
      
       
        
        
        
         O
        
        
         (
        
        
         n
        
        
         l
        
        
         o
        
        
         o
        
        
         g
        
        
         n
        
        
         )
        
       
      
     
    
    (还是
    
     
      
       O 
(
n
l
o
g
2
n
)
        O(nlog^2n)
      
      
       
        
        
        
         O
        
        
         (
        
        
         n
        
        
         l
        
        
         o
        
        
         
          g
         
         
          
           
            
             
              
              
              
               
                2
               
              
             
            
           
          
         
        
        
         n
        
        
         )
        
       
      
     
    
    ?不会进行复杂度分析,但是肯定是可以通过的复杂度)。
    
    
     AC code
    
   
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define lowbit(x) (x&(-x))
#define mid ((l+r)>>1)
#define ls rt<<1
#define rs rt<<1|1
#define lson ls,l,mid
#define rson rs,mid+1,r
using namespace std;
int n,op,l,r,k,m,q,ans,x;
int a[100005];
int tr[400005],maxn[400005];
void push_up(int rt){tr[rt]=tr[ls]+tr[rs];maxn[rt]=max(maxn[ls],maxn[rs]);}
void build(int rt,int l,int r){
	if(l==r){cin>>tr[rt];maxn[rt]=tr[rt];return;}
	build(lson);build(rson);
    push_up(rt);
}
void update(int rt,int l,int r,int ql,int qr,int k){//单点修改为k,图省事直接用的区间修改写的单点修改
	if(l>=ql&&r<=qr){tr[rt]=maxn[rt]=k;return;}
	if(mid>=ql)update(lson,ql,qr,k);
	if(mid<qr)update(rson,ql,qr,k);
	push_up(rt);
}
void update1(int rt,int l,int r,int ql,int qr,int k){//区间模k,区间最大值小于k直接返回,否则暴力修改
    if(l==r){tr[rt]%=k;maxn[rt]=tr[rt];return;}
	if(l>=ql&&r<=qr&&maxn[rt]<k){return;}
	if(mid>=ql&&maxn[ls]>=k)update1(lson,ql,qr,k);
	if(mid<qr&&maxn[rs]>=k)update1(rson,ql,qr,k);
	push_up(rt);
}
int query(int rt,int l,int r,int ql,int qr,int res=0){//查询区间和
	if(l>=ql&&r<=qr) return tr[rt];
	if(mid>=ql)res+=query(lson,ql,qr);
	if(mid<qr)res+=query(rson,ql,qr);
	return res;
}
 
void solve(){
    cin>>n>>q;build(1,1,n);
    while(q--){
        cin>>op;
        if(op==1){cin>>l>>r;cout<<query(1,1,n,l,r)<<endl;}
        else if(op==2){cin>>l>>r>>x;update1(1,1,n,l,r,x);}
        else{cin>>k>>x;update(1,1,n,k,k,x);}
    }
}
signed main(){
    int t=1;
    while (t--)
        solve();
}
如果以上有错误之处可以评论指出。
 
