[ACW]802区间和

tips:

  1.离散化,就是把无限空间中有限个体(稀疏)映射到有限空间中去。

  2.值域范围大,个数少,有的题目要以这些值为下标来做,太大无法保存对应的属性。

  3.整数,保序离散。

  4.相对关系

  5.映射到排序后对应的位置(即下标)

  5.上一个学的算法是trie树(要温习形成长久记忆)

//要学习的编程技巧
/*
把操作给存起来,如插入,查询
有重新组织输入流程的感觉,代码设计架构师?
*/
#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

typedef pair<int ,int > PII;//每个操作是两个数

const  int N=300010;

int n,m;
int a[N],s[N];//a是我们存的数,s是前缀和
//a[x]x是离散化映射的位置

vector<int> alls;//存我们要离散化的值

//插入操作用vector pair 来存
vector<PII> add,query;

//求x值离散化后的结果,find用来离散化
int find(int x){
    int l=0,r=alls.size()-1;
    while(l < r){
        int mid = l+r >>1;
        if(alls[mid] >= x) r=mid;
        else l=mid+1;
    }
    return r+1;//映射到从一开始,前缀和从一开始比较好做,比较好处理边界
}

//先把所有需要操作的数读进来,把所有用到的位置离散化(题目中语言用的是位置)
int main(){
    cin>>n>>m;
    for(int i=0;i<n;i++){
        int x, c;
        cin >> x >> c;
        add.push_back({x,c});

        alls.push_back(x);
    }

    for(int i=0;i<m;i++){
        int l,r;
        cin >> l >> r;
        query.push_back({l,r});

        //把左右区间加到待离散化的数组中去
        alls.push_back(l);
        alls.push_back(r);
    }

    //去重
    sort(alls.begin(),alls.end());
    alls.erase(unique(alls.begin(),alls.end()),alls.end());

    //处理插入
    for(auto item : add){
        int x = find(item.first);
        a[x]+=item.second;
    }

    //预处理前缀和
    for(int i=1; i<= alls.size(); i++){
        s[i]=s[i-1]+a[i];
    }

    //处理询问
    for(auto item : query){
        int l=find(item.first),r=find(item.second);
        cout << s[r] -s[l -1 ]<< endl;
    }

    return 0;
}
View Code
3. 离散化
    vector<int> alls; // 存储所有待离散化的值
    sort(alls.begin(), alls.end()); // 将所有值排序
    alls.erase(unique(alls.begin(), alls.end()), alls.end());    // 去掉重复元素
    
    // 二分求出x对应的离散化的值
    int find(int x)
    {
        int l = 0, r = alls.size() - 1;
        while (l < r)
        {
            int mid = l + r >> 1;
            if (alls[mid] >= x) r = mid;
            else l = mid + 1;
        }
        return r + 1;
    }
模板

好的参考链接:

https://baike.baidu.com/item/%E7%A6%BB%E6%95%A3%E5%8C%96/10501557?fr=aladdin

https://www.cnblogs.com/sun-of-Ice/p/9419857.html

https://blog.csdn.net/weixin_43061009/article/details/82083983

ps:

每天都要在自己想学的东西上投入时间,慢慢来;

时间不会因为自己的懈怠而静止;

实际行动才能产生改变。

posted @ 2020-01-18 22:22  SUMay  阅读(129)  评论(0编辑  收藏  举报