//给你一个序列,有两种操作: //1、给定x和y,将区间[x,y]内的数开方 //2、询问区间和 // // 因为一个longlong类型的数最多开6次方就变成了1,所以对于1操作,我们暴力修改, //对每个节点标记一个flag,表示当前节点掌控的区间有没有全变成1或0 (数据中有0) //如果root->flag==1,就return,因为再怎么改也都还是0或1,不变。 //有多组数据 #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; const int N=1e5+5; int n,m; int type,l,r; struct Tree { bool flag; int l,r,mid; long long sum; }tree[N<<2]; long long read() { char c=getchar();long long num=0,f=1; for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) num=num*10+c-'0'; return num*f; } void build(int root,int l,int r) { tree[root].l=l,tree[root].r=r,tree[root].mid=l+r>>1; if(l==r) { scanf("%lld",&tree[root].sum); tree[root].flag=tree[root].sum<=1; return; } build(root<<1,l,tree[root].mid); build(root<<1|1,tree[root].mid+1,r); tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum; tree[root].flag=tree[root<<1].flag&&tree[root<<1|1].flag; } void modify(int root,int l,int r) { if(tree[root].flag) return; if(tree[root].l==tree[root].r) { tree[root].sum=sqrt(tree[root].sum); tree[root].flag=tree[root].sum<=1; return; } if(l<=tree[root].mid) modify(root<<1,l,r); if(tree[root].mid<r) modify(root<<1|1,l,r); tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum; tree[root].flag=tree[root<<1].flag&&tree[root<<1|1].flag; } long long query(int root,int l,int r) { if(l<=tree[root].l&&tree[root].r<=r) return tree[root].sum; long long sum=0; if(l<=tree[root].mid) sum+=query(root<<1,l,r); if(tree[root].mid<r) sum+=query(root<<1|1,l,r); return sum; } int main() { int tim=0; while(scanf("%d",&n)!=EOF) { printf("Case #%d: ",++tim); build(1,1,n); scanf("%d",&m); for(int i=1;i<=m;++i) { // type=read(),l=read(),r=read(); scanf("%d%d%d",&type,&l,&r); if(l>r) swap(l,r); if(type) printf("%lld ",query(1,l,r)); else modify(1,l,r); } puts(""); } return 0; }