卡了两天了,不想手写 vector,太毒瘤。也不想循环展开,更毒瘤。所以还有什么卡常的办法吗 qwq
#include<cstdio>
#include<vector>
using namespace std;
const int A=5e5+1,N=1e5+1;
int n,q,a[N],cnt[A];
long long ans,t[N];
vector<int>f[A],d[A];
inline long long read(){
register long long x=0;
static char ch=getchar();
while(ch<48)ch=getchar();
while(ch>=48){
x=(x<<3)+(x<<1)+(ch^48);
ch=getchar();
}
return x;
}
inline void write(long long x){
if(x>=10)write(x/10);
putchar(x%10+48);
}
inline void add(int x,int k){
while(x<=n){
t[x]+=k;
x+=(x&-x);
}
}
inline long long query(int x){
register long long ret=0;
while(x){
ret+=t[x];
x-=(x&-x);
}
return ret;
}
inline int fd(int k,int x){return cnt[k]==x?x:f[k][x]==x?x:f[k][x]=fd(k,f[k][x]);}
int main(){
n=read(),q=read();
for(register int i=1;i<=n;i++){
a[i]=read();
add(i,a[i]);
}
for(register int i=1;i<=n;i++){
if(a[i]==1)continue;
d[a[i]].push_back(i);
f[a[i]].push_back(cnt[a[i]]++);
for(register int j=2;j*j<=a[i];j++){
if(a[i]%j==0){
d[j].push_back(i);
f[j].push_back(cnt[j]++);
if(j*j!=a[i]){
d[a[i]/j].push_back(i);
f[a[i]/j].push_back(cnt[a[i]/j]++);
}
}
}
}
while(q--){
register int op=read(),x=read()^ans,y=read()^ans;
if(op==1){
register int k=read()^ans;
if(k==1)continue;
register int st=lower_bound(d[k].begin(),d[k].end(),x)-d[k].begin();
for(register int i=fd(k,st);i<cnt[k]&&d[k][i]<=y;i=fd(k,i+1)){
if(a[d[k][i]]%k==0){
add(d[k][i],-a[d[k][i]]);
add(d[k][i],a[d[k][i]]/=k);
}
if(a[d[k][i]]%k!=0)f[k][i]=i+1;
}
}
else{
ans=query(y)-query(x-1);
write(ans);
putchar('\n');
}
}
return 0;
}