首页 > 其他分享 >高精度差分

高精度差分

时间:2023-01-26 19:22:35浏览次数:42  
标签:高精度 int back 差分 vector alls push size

四、高精度:

1.大整数的存储
2.模拟加法的存储

123+89=212(Ai+Bi+t)

#include <vector>将数组的长度变长
例题

1.高精度减法

#include <iostream>
#include <vector>
using namespace std;
bool cmp(vector<int> &A, vector<int> &B)//判断是否有A>=B
{
    if(A.size()!=B.size()) return A.size()>B.size();
    for(int i=A.size()-1;i>=0;i--)
        if(A[i]!=B[i])
            return A[i]>B[i];
    return true;
}
vector<int> sub(vector<int> &A, vector<int> &B)// C = A - B, 满足A >= B, A >= 0, B >= 0
{
    vector<int> C;
    for (int i = 0, t = 0; i < A.size(); i ++ )
    {
        t = A[i] - t;
        if (i < B.size()) t -= B[i];
        C.push_back((t + 10) % 10);
        if (t < 0) t = 1;
        else t = 0;
    }

    while (C.size() > 1 && C.back() == 0) C.pop_back();//去掉前面的0
    return C;
}
int main()
{
    string a, b;
    vector<int> A, B;
    cin >> a >> b;
    for (int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0');
    for (int i = b.size() - 1; i >= 0; i -- ) B.push_back(b[i] - '0');

    vector<int> C;

    if (cmp(A, B)) C = sub(A, B);
    else C = sub(B, A), cout << '-';

    for (int i = C.size() - 1; i >= 0; i -- ) cout << C[i];
    cout << endl;

    return 0;
}

2.高精度加法

#include <iostream>
#include <vector>

using namespace std;

const int base = 1000000000;

vector<int> add(vector<int> &A, vector<int> &B)
{
    if (A.size() < B.size()) return add(B, A);

    vector<int> C;
    int t = 0;
    for (int i = 0; i < A.size(); i ++ )
    {
        t += A[i];
        if (i < B.size()) t += B[i];
        C.push_back(t % base);
        t /= base;
    }

    if (t) C.push_back(t);
    return C;
}

int main()
{
    string a, b;
    vector<int> A, B;
    cin >> a >> b;

    for (int i = a.size() - 1, s = 0, j = 0, t = 1; i >= 0; i -- )
    {
        s += (a[i] - '0') * t;
        j ++, t *= 10;
        if (j == 9 || i == 0)
        {
            A.push_back(s);
            s = j = 0;
            t = 1;
        }
    }
    for (int i = b.size() - 1, s = 0, j = 0, t = 1; i >= 0; i -- )
    {
        s += (b[i] - '0') * t;
        j ++, t *= 10;
        if (j == 9 || i == 0)
        {
            B.push_back(s);
            s = j = 0;
            t = 1;
        }
    }

    auto C = add(A, B);

    cout << C.back();
    for (int i = C.size() - 2; i >= 0; i -- ) printf("%09d", C[i]);
    cout << endl;

    return 0;
}

五、差分

image-20221231172801808

image-20221231172825795

#include <iostream>
using namespace std;
const int N = 100010;
int n, m;
int a[N], b[N];
void insert(int l, int r, int c)
{
    b[l] += c;
    b[r + 1] -= c;
}
int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
    for (int i = 1; i <= n; i ++ ) insert(i, i, a[i]);
    while (m -- )
    {
        int l, r, c;
        scanf("%d%d%d", &l, &r, &c);
        insert(l, r, c);
    }
    for (int i = 1; i <= n; i ++ ) b[i] += b[i - 1];
    for (int i = 1; i <= n; i ++ ) printf("%d ", b[i]);
    return 0;
}

六、双指针算法

七、区间和与合并

例题

1.区间和

image-20230106111806538 image-20230106111849075
#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];

vector<int> alls;//存入下标容器
vector<PII> add, query;//add增加容器,存入对应下标和增加的值的大小
//query存入需要计算下标区间和的容器
int find(int x)
{
    int l = 0, r = alls.size() - 1;
    while (l < r)//查找大于等于x的最小的值的下标
    {
        int mid = l + r >> 1;
        if (alls[mid] >= x) r = mid;
        else l = mid + 1;
    }
    return r + 1;//因为使用前缀和,其下标要+1可以不考虑边界问题
}

int main()
{
    cin >> n >> m;
    for (int i = 0; i < n; i ++ )
    {
        int x, c;
        cin >> x >> c;
        add.push_back({x, c});//存入下标即对应的数值c

        alls.push_back(x);//存入数组下标x=add.first
    }

    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);//将add容器的add.secend值存入数组a[]当中,
        a[x] += item.second;//在去重之后的下标集合alls内寻找对应的下标并添加数值
    }

    // 预处理前缀和
    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);//在下标容器中查找对应的左右两端[l~r]下标,然后通过下标得到前缀和相减再得到区间a[l~r]的和
        cout << s[r] - s[l - 1] << endl;
    }

    return 0;
}

2.区间和并

image-20230106112058789 image-20230106112118820
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

typedef pair<int, int> PII;

void merge(vector<PII> &segs)
{
    vector<PII> res;

    sort(segs.begin(), segs.end());

    int st = -2e9, ed = -2e9;
    for (auto seg : segs)
        if (ed < seg.first)
        {
            if (st != -2e9) res.push_back({st, ed});
            st = seg.first, ed = seg.second;
        }
        else ed = max(ed, seg.second);

    if (st != -2e9) res.push_back({st, ed});

    segs = res;
}

int main()
{
    int n;
    scanf("%d", &n);

    vector<PII> segs;
    for (int i = 0; i < n; i ++ )
    {
        int l, r;
        scanf("%d%d", &l, &r);
        segs.push_back({l, r});
    }

    merge(segs);

    cout << segs.size() << endl;

    return 0;
}

标签:高精度,int,back,差分,vector,alls,push,size
From: https://www.cnblogs.com/Cathy-cat/p/17068094.html

相关文章

  • 前缀和and差分
    1.前缀和求前缀和的时间复杂度与数据的规模有关,但是用前缀和去求某一区间的和时间复杂度为O(1)一维:一般让下标从1开始,可以避免特判一维前缀和s[i]=a[1]+a[2]+……......
  • 高精度
    当计算位数超过最大存储范围时,无法正常存储而使用数组来存储数据读取stringa,b;cin>>a>>b;//用字符串读取vector<int>A,B;//转换为存储在数组中for(inti......
  • 高精度四则运算
    算法学习的第三天算法学习之高精度四则运算高精度算法(HighAccuracyAlgorithm)是处理大数字的数学计算方法。在一般的科学计算中,会经常算到小数点后几百位或者更多,当然......
  • [简单DP+高精度]围墙重建
    题目描述为了给同学们营造一个良好的学习环境和方便学校的管理,市政府准备对小W就读的学校进行重新规划,占地面积将再次扩大。学校通过领导会议决定,重建学校的围墙。由......
  • 【数组】 差分
    【数组】差分前缀和与差分我在前面的两篇博客里面简要介绍了一下一维、二维数组的前缀和的一些知识点,提到前缀和,那很自然地就会提到差分的概念。首先我们回顾一下前......
  • 模拟与高精度算法
    模拟模拟就是用计算机来模拟题目中要求的操作。模拟题目通常具有码量大、操作多、思路繁复的特点。由于它码量大,经常会出现难以查错的情况,如果在考试中写错是相当浪费时......
  • 区间DP-二维前缀和-差分-6292. 子矩阵元素加 1
    304.二维区域和检索-矩阵不可变DescriptionDifficulty:中等RelatedTopics:设计,数组,矩阵,前缀和给定一个二维矩阵matrix,以下类型的多个请求:计算其子矩形......
  • P3275 [SCOI2011]糖果 差分约束+最短路
    //题意:给定一些限制条件,询问满足条件的任一正数解是什么。(详细题意搜原题)//思路:本题有几个额外信息很关键//最大人数1e5,连出去的边只有0和-1//如果我们......
  • 【学习笔记】差分约束
    1.算法介绍差分约束系统是一种特殊的\(N\)元一次不等式组,它包含\(N\)个变量\(X_1\simX_N\)以及\(M\)个约束条件,每个约束条件是由两个其中的变量做差构成的,形如......
  • 差分两道题
    https://www.acwing.com/activity/content/problem/content/334/参考代码:1//差分的性质运用和基本思维2//差分就不多说了基本操作3//题目要求得到的数都一样的......