线段树裸题
#include<cstdio> #include<cmath> #define ll long long using namespace std; int tag[400005],a[100005]; ll sz[400005]; void update(int t){ tag[t]=tag[t<<1]|tag[t<<1|1]; sz[t]=sz[t<<1]+sz[t<<1|1]; } void modify(int t,int l,int r,int x,int y){ if (r<x || l>y || !tag[t]) return; if (l==r){ sz[t]=(int)sqrt((double)sz[t]); tag[t]=(sz[t]>1); return; } int mid=(l+r)>>1; modify(t<<1,l,mid,x,y); modify(t<<1|1,mid+1,r,x,y); update(t); } void build(int t,int l,int r){ if (l==r){ sz[t]=a[l]; tag[t]=(a[l]>1); return; } int mid=(l+r)>>1; build(t<<1,l,mid); build(t<<1|1,mid+1,r); update(t); } ll query(int t,int l,int r,int x,int y){ if (r<x || l>y) return 0; if (l>=x && r<=y) return sz[t]; int mid=(l+r)>>1; return query(t<<1,l,mid,x,y)+query(t<<1|1,mid+1,r,x,y); } int main(){ int n; scanf("%d",&n); for (int i=1; i<=n; i++) scanf("%d",&a[i]); build(1,1,n); int m; scanf("%d",&m); while (m--){ int cas,l,r; scanf("%d%d%d",&cas,&l,&r); if (cas==2) modify(1,1,n,l,r); else printf("%lld ",query(1,1,n,l,r)); } return 0; }