CF121E Lucky Array
题意
给定序列
解法
考虑可以分块解决。
但是分块的难点在于操作
显然如果我们暴力对
那么我们考虑对所有整块都记录一个
代码:
// 省略火车头
#include <string>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
constexpr int N = 1e5 + 5, M = 705, Q = 1e4 + 5;
int a[N], len;
int plusb[N];
int f[M][Q];
inline int get(register const int& x)
{
return (x - 1) / len;
}
inline int lplace(register const int& x)
{
return x * len + 1;
}
inline int rplace(register const int& x)
{
return lplace(x + 1) - 1;
}
int p[] = { 4, 7, 44, 47, 74, 77, 444, 447, 474, 477, 744, 747, 774, 777, 4444, 4447, 4474, 4477, 4744, 4747, 4774, 4777, 7444, 7447, 7474, 7477, 7744, 7747, 7774, 7777 };
bool flag[N];
int main()
{
register int n, m;
scanf("%d%d", &n, &m);
len = sqrt(n);
for (register int i(0); i < 30; i = -~i) flag[p[i]] = true;
for (register int i(1); i <= n; i = -~i) scanf("%d", &a[i]);
for (register int i(0); i <= len; i = -~i)
{
register int lp(lplace(i)), rp(rplace(i));
for (register int j(lp); j <= rp; j = -~j)
{
f[i][a[j]]++;
}
}
while (m--)
{
string ch;
cin >> ch;
if (ch[0] == 'a')
{
register int l, r, d;
scanf("%d%d%d", &l, &r, &d);
register int ls(get(l)), rs(get(r));
if (ls == rs)
{
for (register int i(l); i <= r; i = -~i)
{
f[get(i)][a[i]]--;
a[i] += d;
f[get(i)][a[i]]++;
}
}
else
{
register int lp = lplace(ls + 1), rp = rplace(rs - 1);
for (register int i(l); i < lp; i = -~i)
{
f[get(i)][a[i]]--;
a[i] += d;
f[get(i)][a[i]]++;
}
for (register int i(rp + 1); i <= r; i = -~i)
{
f[get(i)][a[i]]--;
a[i] += d;
f[get(i)][a[i]]++;
}
register int nl(get(lp)), nr(get(rp));
for (register int i(nl); i <= nr; i++)
{
plusb[i] += d;
}
}
}
else
{
register int sum = 0, l, r;
scanf("%d%d", &l, &r);
register int ls(get(l)), rs(get(r));
if (ls == rs)
{
for (register int i(l); i <= r; i = -~i)
{
sum += flag[a[i] + plusb[get(i)]];
}
}
else
{
register int lp = lplace(ls + 1), rp = rplace(rs - 1);
for (register int i(l); i < lp; i = -~i) sum += flag[a[i] + plusb[get(i)]];
for (register int i(rp + 1); i <= r; i = -~i) sum += flag[a[i] + plusb[get(i)]];
register int nl(get(lp)), nr(get(rp));
for (register int i(nl); i <= nr; i = -~i)
{
for (register int j(0); j < 30; j = -~j)
{
if (plusb[i] > p[j]) continue;
sum += f[i][p[j] - plusb[i]];
}
}
}
printf("%d\n", sum);
}
}
return 0;
}
限时
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现