差分:

例如有一个数组 a[5] = {0,1,2,3,4};
另设一个数组 d[i] = a[i] - a[i-1],i从1开始
这个数组就叫做数组a的差分数组

差分的运用:

1 利用差分数组还原原数组 d[i] = d[i] + d[i-1];
2 原数组中区间[l,r] 的数都加一个k,等价于差分数组: d[l]+=k, d[r+1]-=k;

例子

a[5] = {0,1,2,3,4};
d[5] = {0,1,1,1,1};

还原数组:

d[1] = d[1] + d[0] = 1;
d[2 ] = d[2] + d[1] = 2;
d[3] = d[3] + d[2] = 3;
d[4] = d[4] + d[3] = 4;

区间[1,3] 都加1:

d[1] = d[i] + 1 = 2;
d[4] = d[4] - 1 = 0;
上两行对应 d[l]+=k, d[r+1]-=k
d[1] = d[1] + d[0] = 2;
d[2 ] = d[2] + d[1] = 3;
d[3] = d[3] + d[2] = 4;
d[4] = d[4] + d[3] = 4;
上4行对应还原数组操作

说明:

差分的重要运用在:
“2 原数组中区间[l,r] 的数都加一个k,等价于差分数组: d[l]+=k, d[r+1]-=k;
这样可以避免数据量大的时候超时

例题:

糖糖别胡说,我真的不是签到题目

#include <iostream>

using namespace std;
const int maxn = 1e6+9 ;
int a[maxn],b[maxn],c[maxn];
int d[maxn]={0};//差分数组
int main()
{
   int t;
   cin>>t;
   while(t--)
   {
       int n,m;
       cin>>n>>m;
       for(int i=1;i<=n;i++)
       {
           cin>>a[i]>>b[i];
            d[i]=b[i] - b[i-1];//差分
       }
       for(int i=1;i<=m;i++)
       {
           cin>>c[i];
           //差分
           d[1]++;
          if(c[i]+1<=n) d[c[i]+1]--;
       }
       int cnt  = n;
       int max0= -1e9;
       int max1=-1e9;
       for(int i=1;i<=n;i++)
       {
           d[i] = d[i]+d[i-1];
       }
       for(int i=n;i>=1;i--)
       {
             if(a[i]==1)
           {
              if(d[i]<max0) cnt--;
               max1 = max(max1,d[i]);
           }
            else
           {
                if(d[i]<max1) cnt--;
                 max0 = max(max0,d[i]);

          }
       }
       cout<<cnt<<endl;

   }
    return 0;
}

值周

#include <iostream>

using namespace std;
const int maxn = 1e8+9;
int t[maxn];
int d[maxn] = {0};
int main()
{
    std::ios::sync_with_stdio(false);
    int L,M;
    cin>>L>>M;
    d[1] = 1;
    int ex,sx;
    for(int i=0;i<M;i++)
    {
        cin>>sx>>ex;
        d[sx+1]--;
        if(ex+2<=L+1) d[ex+2]++;
    }
    int cnt = 0;
    for(int i=1;i<=L+1;i++)
    {
        d[i] = d[i] + d[i-1];
        if(d[i]==1) cnt++;
    }
    cout<<cnt<<endl;
    return 0;
}

校门外的树

#include <iostream>

using namespace std;
const int maxn = 1e4+9;
int t[maxn];
int d[maxn] = {0};
int main()
{
    std::ios::sync_with_stdio(false);
    int L,M;
    cin>>L>>M;
    for(int i=1;i<=L+1;i++)
    {
        t[i] = 1;
    }
    d[1] = 1;
    int ex,sx;
    for(int i=0;i<M;i++)
    {
        cin>>sx>>ex;
        d[sx+1]--;
        if(ex+2<=L+1) d[ex+2]++;
    }
    int cnt = 0;
    for(int i=1;i<=L+1;i++)
    {
        d[i] = d[i] + d[i-1];
        if(d[i]==1) cnt++;
    }
    cout<<cnt<<endl;
    return 0;
}