对1开方结果不变,当一个区间的所有的数字斗为1(sum[i] == (t[i].r - t[i].l + 1))时,直接return,要不然就会超时。
不开long long 会RE。
两个case之间有换行。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int maxn = 500010;
LL sum[maxn<<2];
struct Tree
{
LL l , r ;
}t[maxn << 2];
LL n , m ;
LL s[maxn];
LL q;
void pushup(LL i)
{
sum[i] = sum[i<<1] + sum[i<<1|1];
}
void build(LL l ,LL r ,LL i)
{
if(l == r)
{
t[i].l = t[i].r = l;
scanf("%lld",&sum[i]);
return ;
}
t[i].l = l;
t[i].r = r;
LL mid = (l+r) >> 1;
build(l,mid,i<<1);
build(mid+1,r,i<<1|1);
pushup(i);
}
void update(LL l,LL r,LL i)
{
if(t[i].l == t[i].r)
{
sum[i] = sqrt(sum[i]);
return;
}
if( l <= t[i].l && r >= t[i].r && sum[i] == (t[i].r - t[i].l + 1) ) return;
LL mid = (t[i].l + t[i].r)/2;
if(l<=mid){update(l,r,i<<1);}
if(r> mid){update(l,r,i<<1|1);}
pushup(i);
}
void query(LL l, LL r ,LL i)
{
if(l <= t[i].l && r >= t[i].r)
{
q += sum[i];
return ;
}
LL mid = (t[i].l + t[i].r) >> 1;
if(l<=mid){query(l,r,i<<1);}
if(r> mid){query(l,r,i<<1|1);}
}
int main()
{
LL kase = 1;
while(cin >> n)
{
memset(sum,0,sizeof(sum));
build(1,n,1);
printf("Case #%d:\n",kase++);
scanf("%lld",&m);
int type , from , to;
for(LL i = 0 ; i < m ; i++)
{
q = 0;
scanf("%d%d%d",&type,&from,&to);
if (from > to) swap(from, to);
if(type == 1)
{
query(from , to , 1);
printf("%lld\n",q);
}
else
{
update(from , to , 1);
}
}
printf("\n");
}
return 0;
}