hdu4027刚学线段树,求佬为什么不对

  1. http://acm.hdu.edu.cn/showproblem.php?pid=4027

#include <iostream>

#include <cmath>

using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
ll a[N];    ll tree[4*N];   //ll tag[4*N];
ll ls(ll p)    {return p<<1;}
ll rs(ll p)    {return p<<1|1;}
void push_up(ll p)
{
    tree[p] = tree[ls(p)] + tree[rs(p)];
}
void setree(ll p, ll pl, ll pr)
{
    if(pl == pr)    {tree[p] = a[pl];   return;}
    ll mid = (pl + pr) >> 1;
    setree(ls(p), pl, mid);
    setree(rs(p), mid+1, pr);
    push_up(p);
}/*
void addtag(ll p)
{
    if(!tag[p] && tag[ls(p)] && tag[rs(p)])        //
        tag[p] = 1;
}*/
ll sqrt_it(ll p, ll pl, ll pr)
{
    if(tree[p] != pr-pl+1){
        if(pl == pr)    {tree[p] = sqrt(tree[p]);   return tree[p];}
        ll mid = (pl + pr) >> 1;
        ll aftsqrt = sqrt_it(ls(p), pl, mid) + sqrt_it(rs(p), mid+1, pr);
        //addtag(p);
        push_up(p);
        return aftsqrt;
    }
    else    return tree[p];
}
void update(ll L, ll R, ll p, ll pl, ll pr)
{
    if(L <= pl && R >= pr){
        tree[p] = sqrt_it(p, pl, pr);
        //addtag(p);
        return;
    }
    ll mid = (pl + pl) >> 1;
    if(L <= mid)  update(L, R, ls(p), pl, mid);
    if(R > mid)   update(L, R, rs(p), mid+1, pr);
    push_up(p);
    //addtag(p);
    //tree[p] = sqrt_it(p, pl, pr);
}
ll query(ll L, ll R, ll p, ll pl, ll pr)
{
    if(L <= pl && R >= pr)  return tree[p];
    ll res = 0;
    ll mid = (pl + pr) >> 1;
    if(L <= mid)    res += query(L, R, ls(p), pl, mid);
    if(R > mid)     res += query(L, R, rs(p), mid+1, pr);
    return res;
}
void swap(int &a, int &b)
{
    int tmp = a;
    a = b;
    b = tmp;
}
int main()
{
    int n;  int cnt = 0;
    while(scanf("%d",&n) != EOF){
        //int n;  cin >> n;
        cout << "Case #" << ++cnt << ":" << endl;
        for(int i = 1; i <= n; i++)    cin >> a[i];
        int m;  cin >> m;
        while(m--){
            int t,x,y;  scanf("%d%d%d",&t,&x,&y);
            if(x > y)   swap(x, y);
            if(!t)  update(x, y, 1, 1, n);
            if(t)   {
                cout << query(x, y, 1, 1, n) << endl;
            }
        }
    }
    return 0;
}



#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;

const int maxn = 1e5+10;
const int maxq = 1e5+10;
int n, m, a[maxn];
struct Query { int t, l, r; } Q[maxq];
int sqrtq, sqrtl[maxq], sqrtr[maxq], sqrtcnt;

void init() {
    sqrtq = sqrt(n);
    sqrtcnt = (n-1) / sqrtq + 1;
    for (int i = 0; i < sqrtcnt; i++) {
        sqrtl[i] = i * sqrtq;
        sqrtr[i] = min(n-1, (i+1)*sqrtq-1);
    }
}

int sq(int x) { return int(sqrt(x)); }

int main() {
    int T = 0;
    while (scanf("%d", &n) != EOF) {
        T++;
        memset(a, 0, sizeof(a));
        for (int i = 0; i < n; i++) {
            scanf("%d", &a[i]);
        }
        init();
        scanf("%d", &m);
        for (int i = 0; i < m; i++) {
            int t, l, r;
            scanf("%d%d%d", &t, &l, &r);
            l--; r--;
            Q[i].t = t; Q[i].l = l; Q[i].r = r;
            if (t == 0) {
                int sl = sqrtl[l], sr = sqrtr[l];
                for (int j = l; j <= r; ) {
                    if (j <= sr) {
                        a[j] = sq(a[j]);
                        j++;
                    } else {
                        sl++; sr = sqrtr[sl];
                    }
                }
            }
        }
        printf("Case #%d:\n", T);
        for (int i = 0; i < m; i++) {
            int t = Q[i].t, l = Q[i].l, r = Q[i].r;
            if (t == 1) {
                int ans = 0;
                int sl = sqrtl[l], sr = sqrtr[l];
                for (int j = l; j <= r; ) {
                    if (j <= sr) {
                        ans += a[j];
                        j++;
                    } else {
                        sl++; sr = sqrtr[sl];
                    }
                }
                printf("%d\n", ans);
            }
        }
        printf("\n");
    }
    return 0;
}