[Ynoi2012]D1T1
套路的根号分治啊
我们设置一个值\(S\)
对于\(S\leq x\)的操作,我们直接暴力修改,显然这样只会修改\(\frac{n}{S}\)次,所以我们需要一个能够\(O(1)\)修改的数据结构,自然是首选分块
对于\(S>x\)的操作,我们对于每一个\(x\)维护一个块,我们维护这个块的前缀和就好了,复杂度是\(O(S)\)的
查询的时候先用分块查一下区间和,复杂度\(O(S+\frac{n}{S})\),之后对于每一个\(x<S\)的块我们单独\(O(1)\)求一下,复杂度是\(O(S)\)
理论上自然是\(S=\sqrt{n}\)的时候取到了最优的复杂度,但是我们根据一些奇怪的常数原因,可以魔改一波块大小
代码
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define re register
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
const int maxn=2e5+5;
const int mod=1e9+7;
int n,m,sz;
int pr[500][500],sum[500];
int pre[maxn],id[maxn],l[5000];
inline int qm(int a) {return a>=mod?a-mod:a;}
struct Block {
int a[maxn],tag[5000];
inline void change(int pos,int v) {
a[pos]=qm(a[pos]+v);
tag[id[pos]]=qm(tag[id[pos]]+v);
}
inline int ask(int x) {
int now=0;
for(re int i=1;i<id[x];i++) now=qm(now+tag[i]);
for(re int i=l[id[x]];i<=x;i++) now=qm(now+a[i]);
return now;
}
}B;
inline int find(int x,int y) {return !(y%x)?y/x:y/x+1;}
inline int solve(int x,int y) {
if(!y) return 0;
return qm(1ll*(find(x,y)-1)*sum[x]%mod+pr[x][(y%x)?y%x:x]);
}
int main() {
n=read(),m=read();
for(re int i=1;i<=n;i++) pre[i]=(pre[i-1]+read())%mod;
sz=std::sqrt(n);int L=1,tot=0;sz=250;
while(L<=n) {
l[++tot]=L;
for(re int i=L;i<=min(L+sz-1,n);i++) id[i]=tot;
L+=sz;
}
int op,x,y,v;
while(m--) {
op=read(),x=read(),y=read();
if(op==2) {
int ans=(pre[y]-pre[x-1]+mod)%mod;
ans=(ans+B.ask(y)-B.ask(x-1))%mod;
for(re int i=1;i<sz;i++) ans=(ans+solve(i,y)-solve(i,x-1))%mod;
printf("%d\n",(ans+mod)%mod);
}
if(op==1) {
v=read();
if(x>=sz) {while(y<=n) B.change(y,v),y+=x;continue;}
sum[x]=(sum[x]+v)%mod;
for(re int i=y;i<=x;i++) pr[x][i]=qm(pr[x][i]+v);
}
}
return 0;
}
[Ynoi2012]D1T1的更多相关文章
- Luogu P5309 [Ynoi2012]D1T1
小清新分块题,从头到尾都十分套路,和CXR大佬一起YY了一下就出来了 首先套路地设个阈值\(S\),把修改的\(x\)分成大于\(S\)和小于等于\(S\)两部分,然后我们考虑分别求解这两部分 \(x ...
- 【洛谷5309】[Ynoi2012] D1T1(分块)
点此看题面 大致题意: 两种操作,区间求和,将形如\(ax+y\)的位置的元素值加\(z\). 分块 这种题目显然就是按照\(x\)与\(\sqrt n\)的大小关系来分块. 对于\(x>\sq ...
- 洛谷P5524:[Ynoi2012]D1T1——题解
https://www.luogu.org/problem/P5524 看着能做就当线段树复健题了. 根据高中知识我们有 $sin(a+b)=sin(a)cos(b)+cos(a)sin(b)$ $c ...
- [2018HN省队集训D1T1] Tree
[2018HN省队集训D1T1] Tree 题意 给定一棵带点权树, 要求支持下面三种操作: 1 root 将 root 设为根. 2 u v d 将以 \(\operatorname{LCA} (u ...
- 嵊州D1T1 总统先生,一路走好!
嵊州D1T1 总统先生,一路走好! 在总统先生的所有财产就是 n 杯黑咖啡,咖啡店可以用 m 个空杯子换一杯黑咖啡. 因为总统的特殊身份,心地善良而心生怜悯的咖啡店店长决定先借给总统一杯黑咖啡,只要他 ...
- 2017.10.1 国庆清北 D1T1 zhx的字符串题
题目背景 2017国庆清北D1T1 题目描述 你是能看到第一题的 friends 呢. ——hja 何大爷对字符串十分有研究,于是天天出字符串题虐杀 zhx.何大爷今天为 字符串定义了新的权值计算方法 ...
- NOIP2016 D1T1 玩具迷題(toy)
题目描述 小南有一套可爱的玩具小人, 它们各有不同的职业. 有一天, 这些玩具小人把小南的眼镜藏了起来. 小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的面朝圈外.如下图: 这时singer告诉 ...
- 计蒜客模拟赛D1T1 蒜头君打地鼠:矩阵旋转+二维前缀和
题目链接:https://nanti.jisuanke.com/t/16445 题意: 给你一个n*n大小的01矩阵,和一个k*k大小的锤子,锤子只能斜着砸,问只砸一次最多能砸到多少个1. 题解: 将 ...
- 集训 D1T1 clique
将点(xi,wi)看成区间(xi-wi,xi+wi),那么两个点有连边当且仅当两个区间没有公共点.删去所有包含其它区间的区间,在剩下的区间中每次贪心取一个能取的坐标最小的区间. #include< ...
随机推荐
- iOS进阶二-KVC
概述 KVC的全程是Key-Value Coding, 俗称"键值编码",可以通过一个key来访问属性 常见的AP有 - (void)setValue:(nullable id)v ...
- ARM GNU 专有符号
1. @ 表示注释从当前位置到行尾的字符. 2. # 注释掉一整行. 3. ; 新行分隔符.
- jq给页面添加覆盖层遮罩的实例
先引入jq代码,然后代码如下: $(function(){ var docHeight = $(document).height(); //获取窗口高度 $('body').append('<d ...
- Windows cd
显示当前目录名或改变当前目录. CHDIR [/D] [drive:][path]CHDIR [..]CD [/D] [drive:][path]CD [..] .. 指定要改成父目录. 键入 C ...
- springboot集成websocket实现向前端浏览器发送一个对象,发送消息操作手动触发
工作中有这样一个需示,我们把项目中用到代码缓存到前端浏览器IndexedDB里面,当系统管理员在后台对代码进行变动操作时我们要更新前端缓存中的代码怎么做开始用想用版本方式来处理,但这样的话每次使用代码 ...
- HttpClient 使用案例
package com.qifeng.config.ygx.common.utils; import com.alibaba.fastjson.JSON; import com.alibaba.fas ...
- System.Math.cs
ylbtech-System.Math.cs 1. 程序集 mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c56193 ...
- java.sql.SQLSyntaxErrorException: ORA-00932: 数据类型不一致: 应为 NUMBER, 但却获得 BINARY
2019-07-24 17:24:35 下午 [Thread: http-8080-4][ Class:net.sf.ehcache.store.disk.Segment Method: net.sf ...
- idea从github中pull或者push成功之后ssm项目全部controller报红色下划线的解决方案
某次从github上pull下来之后,报出如下一堆红色波浪线错误 解决方法: 在随便一个红色波浪线处,按下alt+enter,点击add maven dependency, 选中所有,点击添加即可,此 ...
- multiprocessing多进程(31-04)创建进程的两种方式
一个进程可以寄生多个线程. CPU核数与进程个数是统一的, 若进程多于核数,那么只有等待上一进程执行完才能被执行. ------------------第一种进程创建方式--------------- ...