题意:给你n个数,1,查询区间和,2,把区间每个数开根
题解:可以发现1e9开5次根就变成1了,所以不用lazy直接暴力更新到叶子节点即可,当这个区间每个数都是0或1就不用下传了,
/**************************************************************
Problem: 3211
User: walfy
Language: C++
Result: Accepted
Time:2408 ms
Memory:4820 kb
****************************************************************/
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fi first
#define se second
#define db double
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define vi vector<int>
#define mod 1000000007
#define ld long double
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pii pair<int,int>
//#define cd complex<double>
#define ull unsigned long long
#define base 1000000000000000000
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define fio ios::sync_with_stdio(false);cin.tie(0)
template<typename T>
inline T const& MAX(T const &a,T const &b){return a>b?a:b;}
template<typename T>
inline T const& MIN(T const &a,T const &b){return a<b?a:b;}
inline void add(ll &a,ll b){a+=b;if(a>=mod)a-=mod;}
inline void sub(ll &a,ll b){a-=b;if(a<0)a+=mod;}
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
inline ll qp(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
inline ll qp(ll a,ll b,ll c){ll ans=1;while(b){if(b&1)ans=ans*a%c;a=a*a%c,b>>=1;}return ans;}
using namespace std;
const double eps=1e-8;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int N=100000+10,maxn=400000+10,inf=0x3f3f3f3f;
struct segtree{
ll val[N<<2];bool ok[N<<2];
void pushup(int rt)
{
val[rt]=val[rt<<1]+val[rt<<1|1];
ok[rt]=(ok[rt<<1]&ok[rt<<1|1]);
}
void build(int l,int r,int rt)
{
if(l==r)
{
scanf("%lld",&val[rt]);
if(val[rt]==0||val[rt]==1)ok[rt]=1;
return ;
}
int m=(l+r)>>1;
build(ls);build(rs);
pushup(rt);
}
void update(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R&&ok[rt])return ;
if(l==r)
{
val[rt]=sqrt(val[rt]);
if(val[rt]==0||val[rt]==1)ok[rt]=1;
return ;
}
int m=(l+r)>>1;
if(L<=m)update(L,R,ls);
if(m<R)update(L,R,rs);
pushup(rt);
}
ll query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)return val[rt];
int m=(l+r)>>1;
ll ans=0;
if(L<=m)ans+=query(L,R,ls);
if(m<R)ans+=query(L,R,rs);
return ans;
}
}tree;
int main()
{
int n;scanf("%d",&n);
tree.build(1,n,1);
int q;scanf("%d",&q);
while(q--)
{
int op,l,r;
scanf("%d%d%d",&op,&l,&r);
if(op==1)printf("%lld
",tree.query(l,r,1,n,1));
else tree.update(l,r,1,n,1);
}
return 0;
}
/********************
4
1 100 5 5
5
1 1 2
2 1 2
1 1 2
2 2 3
1 1 4
********************/