方法应该也许可能没有很大的问题。
#include<bits/stdc++.h>
#define int long long
using namespace std;
namespace Fread {
const int SIZE = 16;
char buf[SIZE], *S, *T;
inline char getchar() {
if (S == T) {
T = (S = buf) + fread(buf, 1, SIZE, stdin);
if (S == T) return '\n';
}
return *S++;
}
}
namespace Fwrite {
const int SIZE = 65536;
char buf[SIZE], *S = buf, *T = buf + SIZE;
inline void flush() {
fwrite(buf, 1, S - buf, stdout);
S = buf;
}
inline void putchar(char c) {
*S++ = c;
if (S == T) flush();
}
struct NTR {
~ NTR() { flush(); }
} ztr;
}
#ifdef ONLINE_JUDGE
#define getchar Fread :: getchar
#define putchar Fwrite :: putchar
#endif
namespace Fastio {
struct Reader {
template<typename T>
Reader& operator >> (T& x) {
char c = getchar();
T f = 1;
while (c < '0' || c > '9') {
if (c == '-') f = -1;
c = getchar();
}
x = 0;
while (c >= '0' && c <= '9') {
x = (x * 10 + (c - '0'));
c = getchar();
}
x *= f;
return *this;
}
Reader& operator >> (char& c) {
c = getchar();
while (c == '\n' || c == ' ') c = getchar();
return *this;
}
Reader& operator >> (char* str) {
int len = 0;
char c = getchar();
while (c == '\n' || c == ' ') c = getchar();
while (c != '\n' && c != ' ') {
str[len++] = c;
c = getchar();
}
str[len] = '\0';
return *this;
}
Reader(){}
} cin;
const char endl = '\n';
struct Writer {
template<typename T>
Writer& operator << (T x) {
if (x == 0) { putchar('0'); return *this; }
if (x < 0) { putchar('-'); x = -x; }
static int sta[45];
int top = 0;
while (x) { sta[++top] = x % 10; x /= 10; }
while (top) { putchar(sta[top] + '0'); --top; }
return *this;
}
Writer& operator << (char c) {
putchar(c);
return *this;
}
Writer& operator << (char* str) {
int cur = 0;
while (str[cur]) putchar(str[cur++]);
return *this;
}
Writer& operator << (const char* str) {
int cur = 0;
while (str[cur]) putchar(str[cur++]);
return *this;
}
Writer(){}
} cout;
}
#define cin Fastio :: cin
#define cout Fastio :: cout
#define endl Fastio :: endl
const int N=2e5+5,M=5e2+5,mod=1e9+7;
int a[N],sum[M],s[M][M];
int lt[M],rt[M],belong[N],tot,block,n,m;
void build(){
block=(int)sqrt((double)n);
tot=n/block;
if(n%block) tot++;
for(int i=1;i<=tot;i++){
lt[i]=(i-1)*block+1;
rt[i]=i*block;
}rt[tot]=n;
for(int i=1;i<=n;i++){
belong[i]=(i-1)/block+1;
sum[belong[i]]+=a[i];
}
}
void change(int x,int y,int k){
if(x>=block){
for(int i=y;i<=n;i+=x) a[i]+=k,sum[belong[i]]+=k;
return;
}
for(int i=y;i<=x;i++) s[x][i]+=k;
}
int ask(int x,int y){
int ans=0;
if(belong[x]==belong[y]){
for(int i=x;i<=y;i++) ans+=a[i];
}
else{
for(int i=x;i<rt[x];i++) ans+=a[i];
for(int i=lt[y];i<=y;i++) ans+=a[i];
for(int i=belong[x]+1;i<=belong[y]-1;i++) ans+=sum[i];
}
for(int i=1;i<=tot;i++) ans+=s[i][y%i]-s[i][(x-1)%i]+s[i][i]*(y/i-(x-1)/i);
return ans;
}
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
for(int _=1,op,x,y,k;_<=m;_++){
cin>>op>>x>>y;
if(op==1){
cin>>k;
change(x,y,k);
}
if(op==2){
cout<<ask(x,y)%mod<<endl;
}
}
return 0;
}