Codeforces1000C-一维差分

(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦

闲话:

 听学长说这就是个简单差分,然而一脸懵逼,差分是啥意思咯???

 这么理解吧。比如你用树状数组,你要给区间[L, R]的数字加上一个数x,你会这样写: update(L, x) && update(R + 1, -x)。你要求区间[L, R]数字和时,你会这样写: sum(R) - sum(L - 1)
 可能差分就是这么个意思吧。对于一段区间,一边操作是”加”,另一边操作是”减”。这样得差就处理了一个区间的情况。
 !!!啊,是这么个意思吗?那位大佬有见解,一定要指出来啊!

思路:

 原题目描述在最下面.
 对于一个线段[L, R],把它的覆盖区域全部加1。操作就是: sum[L]++ && sum[r + 1]--。然后在O(n)枚举。还有些细节看代码吧。

AC代码:

#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef long long LL;
const int inf=2e9+1e8+1234;
const LL linf=8e18+9e17;
const int N = 2e5+7;
int n;
map<LL,int> mp;
pair<LL,LL> g[N];
LL cnt[N];
vector<LL> ar;
int main(int argc, char const *argv[]){
  while(~scanf("%d", &n)){
    memset(cnt, 0, sizeof(cnt));
    mp.clear();ar.clear();
    for(int i = 0; i < n; ++i){
      scanf("%lld%lld", &g[i].fi, &g[i].se);
      g[i].se++;
      mp[g[i].fi]++;mp[g[i].se]--;
      ar.push_back(g[i].fi);
      ar.push_back(g[i].se);
    }
    //这两行是为了把所有的数字去重,只保留一个
    sort(ar.begin(), ar.end());
    ar.erase(unique(ar.begin(), ar.end()), ar.end());
    int tmp = 0;
    LL last = 0;
    for(auto x: ar){
      if(x != ar[0])cnt[tmp] += x - last;
      tmp += mp[x];
      last = x;
    }
    for(int i = 1; i <= n; ++i){
      printf("%lld ", cnt[i]);
    }
  }
  return 0;
}


题目描述:

这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_39599067/article/details/81046899