***又是超时的问题,当一个区间全是1时,再去开方和不开方是一样的,所以在这一步不需要再往底层递归了***
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <stack> #include <queue> #include <cmath> using namespace std; typedef long long LL; #define oo 0x3f3f3f3f #define N 201000 struct node { int l, r; int len() { return r-l+1; } LL s; } tree[N*4]; LL A[N]; void build(int l, int r, int rt) { tree[rt].l=l; tree[rt].r=r; if(l==r) { tree[rt].s=A[l]; return ; } int mid=(l+r)/2; build(l, mid, rt*2); build(mid+1, r, rt*2+1); tree[rt].s=tree[rt*2].s+tree[rt*2+1].s; } void update(int l, int r, int rt) { if(tree[rt].len()==tree[rt].s)//当一个区间全是1时 return ; if(tree[rt].r<l || tree[rt].l>r) return ; if(tree[rt].l>=l && tree[rt].r<=r && tree[rt].l==tree[rt].r) { tree[rt].s=(LL)sqrt(tree[rt].s); return ; } int mid=(tree[rt].l+tree[rt].r)/2; if(r<=mid) update(l, r, rt*2); else if(l>mid) update(l, r, rt*2+1); else { update(l, mid, rt*2); update(mid+1, r, rt*2+1); } tree[rt].s=tree[rt*2].s+tree[rt*2+1].s; } LL query(int l, int r, int rt) { if(tree[rt].l==l && tree[rt].r==r) return tree[rt].s; int mid=(tree[rt].l+tree[rt].r)/2; if(r<=mid) return query(l, r, rt*2); else if(l>mid) return query(l, r, rt*2+1); else { LL x=query(l, mid, rt*2); LL y=query(mid+1, r, rt*2+1); return x+y; } } int main() { int n, m, op, a, b, cas=1; while(~scanf("%d", &n)) { for(int i=1; i<=n; i++) scanf("%I64d", &A[i]); scanf("%d", &m); build(1, n, 1); printf("Case #%d:\n", cas++); while(m--) { scanf("%d%d%d", &op, &a, &b); if(a>b) swap(a, b); if(op==0) update(a, b, 1); else printf("%I64d\n", query(a, b, 1)); } printf("\n"); } return 0; }
时间: 2024-11-10 14:27:40