ABC 379(E-F)
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;
}