等差数列加
等差数列加
根号分治
等差数列加 - 题目 - Daimayuan Online Judge
设一个阈值
给等差数列的位置上加 k
- 若公差 d >= M, 则暴力加,每次操作复杂度最高为
- 若公差 d < M, 则可以打标记记录下公差为 , 第一个加的位置为 ,给这个等差数列打上一个 +k 的标记
查询
- 本来的这个数经过暴力修改后为
- 再加上打标记的,枚举公差 , 若满足 , 则可以加,即 , 一共有 个 d 要枚举,复杂度为
每次操作复杂度为 , 时取到最小值,总复杂度为
调试技巧:
- 可根据分治的两种情况的常数,选择 M, 不一定严格是
- 对拍的话不用再打个暴力,改几个 M 不同的值,如果不一样就一定错了
其他根号算法
- 图染色
- 莫队
- 整除分块
- 和为 n 的一些数(取值为 1~n),最多有 种取值(等差数列前 n 项和可推导出)
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
using namespace std;
#define endl "\n"
typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5 + 10, M = 500;
int n, q;
ll tag[M][M];
ll a[N];
int main()
{
scanf("%d%d", &n, &q);
while(q--)
{
int op;
scanf("%d", &op);
if (op == 1)
{
int x, y, d;
scanf("%d%d%d", &x, &y, &d);
if (x >= M)
{
for (int i = y; i <= n; i += x)
a[i] += d;
}
else
tag[x][y] += d;
}
else
{
int x;
scanf("%d", &x);
ll ans = a[x];
for (int i = 1; i < M; i++)
ans += tag[i][x % i];
cout << ans << endl;
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!