ABC 379(E-F)

ABC379

E

赛场上真想去打高精来着但是高精复杂度其实是错的。。会变成n方小丑
所以原本想了一个暴力9*nlog的做法就寄了(想着维护每个数每一位10的几次方然后加起来。。。)
设以s[i]是以i为左端点的所有区间和,那么\({s[i]=s[i+1]+i*\sum_{j=0}^{n-i}10^j}\)
那么ans就是\(\sum s[i]\)
s[i]用前缀和预处理变换可以按位计算答案

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define int long long
#define pii pair<int, int>
#define mkp make_pair
using namespace std;
const int N = 3e5 + 5;
int pre[N], ans[N];
signed main()
{
    ios::sync_with_stdio(false);
    int n;
    cin >> n;
    string s;
    cin >> s;
    s = '1' + s;
    for (int i = 1; i <= n; i++){
        pre[i] = pre[i - 1] + i * (s[i] - '0');
    }
    int rem=0;
    for(int i=n;i>=1;i--){
        ans[i]=(rem+pre[i])%10;
        rem=(pre[i]+rem)/10;
    }
    if(rem!=0){
        cout<<rem;
    }
    for(int i=1;i<=n;i++)cout<<ans[i];
    cout<<endl;
}

F

单调栈二分或者单调栈树状数组


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
#define mkp make_pair
using namespace std;
const int N = 2e5 + 5;
int pre[N], ans[N],t[N],h[N];
vector<pii>vt[N];
#define lowbit(x) (x&(-x))
int que(int x){
    int res=0;
    while(x>0){
        res+=t[x];
        x-=lowbit(x);
    }
    return res;
}
void upd(int x,int k){
    while(x<N){
        t[x]+=k;
        x+=lowbit(x);
    }
}

signed main()
{
    ios::sync_with_stdio(false);
    int n, q;
    cin >> n >> q;
    stack<int> sta;
    for (int i = 1; i <= n; i++)
    {
        cin >> h[i];
    }
    for(int i=1;i<=q;i++){
        int l,r;cin>>l>>r;
        vt[l].push_back(mkp(r,i));
    }
    for(int i=n;i>=1;i--){
        for(auto j:vt[i]){
            ans[j.second]=que(n)-que(j.first);
        }   
        while(!sta.empty()&&h[sta.top()]<h[i])upd(sta.top(),-1),sta.pop();
        sta.push(i);upd(i,1);
    }
    for(int i=1;i<=q;i++)cout<<ans[i]<<endl;
}
posted @ 2024-11-10 17:34  lyrrr  阅读(12)  评论(0编辑  收藏  举报