2-1791F
题意:
思路:首先发现对于每一个数,最多被只会被操作3次,就会变成1。可以用线段树,维护区间和,如果区间和等于区间长度,则无需操作,时间复杂度为3nlog(n);
考虑到线段树的代码太多,
也可以,现予处理出每个数的前三次操作,用树状数组,记录每个点的操作次数。
代码:
点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 10;
int a[N][4],tree[N];
int n,q;
int ck(int x)
{
int res=0;
while(x)
{
res+=x%10;
x=x/10;
}
return res;
}
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int k)
{
while(x<=n)
{
tree[x]+=k;
x+=lowbit(x);
}
}
int ser(int x)//求sum 1~x
{
int ans=0;
while(x>0)
{
ans+=tree[x];
x-=lowbit(x);
}
return ans;
}
void solve()
{
cin>>n>>q;
for(int i=0;i<=n+1;i++) tree[i]=0;
for(int i=1;i<=n;i++)
{
cin>>a[i][0];
a[i][1]=ck(a[i][0]);
a[i][2]=ck(a[i][1]);
a[i][3]=ck(a[i][2]);
}
int l,r,op,x;
for(int i=1;i<=q;i++)
{
cin>>op;
if(op==1)
{
cin>>l>>r;
add(l,1);
add(r+1,-1);
}
else
{
cin>>x;
int w=ser(x);
if(x-1>0) w-ser(x-1);
w=min(w,3ll);
// cout<<w<<"\n";
cout<<a[x][w]<<"\n";
}
}
}
signed main() {
cin.tie(nullptr)->sync_with_stdio(false);
int t=1;
cin>>t;
while(t--)
{
solve();
}
return 0 ^ 0;
}
本文作者:xxj112
本文链接:https://www.cnblogs.com/xxj112/p/17839468.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步