2021桂林ccpc B. A Plus B Problem,set维护

Problem - B - Codeforces

网上题解都是用线段树维护,弱狗属实看不懂,去问了问学长set的做法,wa了24发终于过了

一开始细节没写好wa了十几发,后来就开始T,疯狂T,我甚至怀疑louer_bound太慢了,去网上查了查,发现还真是这样

最后终于过了,由于网上找不到set作法题解搞得过程曲折 艰辛(弱狗哭了)

具体思路

 只有9才会受溢出影响,所以存非9

其中判断这一位的后面有没有溢出用upper_bound 判断,9不影响,下一个非9才会影响

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#include <iomanip>//io控制头文件 cout<<fixed<<setprecision(3)<<ans<<"\n";     
#define ms(x,n) memset(x,n,sizeof x)
#define endl '\n'
#define pii pair<int,int> 
#define M(a,b) make_pair(a,b)
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int mod = 998244353;
const int N = 1e6 + 10;
int n, m, t;
int a[4][N], b[N];
char s[N];
set<int> v;
int _gcd(int a, int b) {
    return b > 0 ? _gcd(b, a % b) : a;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin >> n >> m;
    cin >> (s + 1);
    for (int i = 1;i <= n;i++) {
        a[1][i] = s[i] - '0';
    }
    cin >> (s + 1);
    for (int i = 1;i <= n;i++) {
        a[2][i] = s[i] - '0';
    }
    int fg = 0;
    for (int i = n;i;i--) {
        if (a[1][i] + a[2][i] != 9) {
            v.insert(i);
        }
        if (a[1][i] + a[2][i] + fg >= 10) {
            b[i] = 1;
            a[3][i] = (a[1][i] + a[2][i] + fg) % 10;
            fg = 1;
        }
        else {
            a[3][i] = (a[1][i] + a[2][i] + fg);
            fg = 0;
        }
    }
    v.insert(0);
    int r, c, d;
    int ans;
    while (m--) {
        cin >> r >> c >> d;
        auto itp = v.upper_bound(c);
        bool f = false;
        if (itp == v.end());
        else {
            if (a[1][*itp] + a[2][*itp] > 9) f = true;
        }
        if (a[r][c] == d) { cout << (a[1][c] + a[2][c] + f)%10 << " " << 0 << endl; continue; }    //相等
        if (a[1][c]+a[2][c]+f<=9) {
            if (a[(r == 1) ? 2 : 1][c] + d + f< 10) {           //0 0
                a[3][c] = a[(r == 1) ? 2 : 1][c] + d + f;
                a[r][c] = d;
                if (a[1][c] + a[2][c] == 9) v.erase(c);                   //要统一更新!
                else v.insert(c);
                cout << a[3][c] << " " << 2 << endl;
                continue;
            }
            else {                                                       //0 1
                ans =2;
                a[3][c] = (a[(r == 1) ? 2 : 1][c] + d + f) % 10;
                a[r][c] = d;
                if (a[1][c] + a[2][c] == 9) v.erase(c);
                else v.insert(c);
                auto it = v.lower_bound(c);
                it--;
                if (*it)              //0不能算上
                    ans += c - *it;
                else ans += c - *it - 1;
                cout << a[3][c] << " " << ans << endl;
            }
        }
        else {
            if (a[(r == 1) ? 2 : 1][c] + d + f< 10) {    //之前溢现在不溢了   //1 0
                ans = 2;
                a[3][c] = (a[(r == 1) ? 2 : 1][c] + d + f) % 10;
                a[r][c] = d;
                if (a[1][c] + a[2][c] == 9) v.erase(c);
                else v.insert(c);
                auto it = v.lower_bound(c);
                it--;
                if(*it)
                  ans += c - *it;
                else ans += c - *it-1;
                cout << a[3][c] << " " << ans << endl;
                continue;
            }
            else {    //之前溢现在溢                                    //1 1
                ans = 2;
                a[3][c] = (a[(r == 1) ? 2 : 1][c] + d + f) % 10;
                a[r][c] = d;
                if (a[1][c] + a[2][c] == 9) v.erase(c);
                else v.insert(c);
                cout << a[3][c] << " " << ans << endl;
            }
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值