Description
Input
Output
每次x=1时,每行一个整数,表示这次旅行的开心度
Sample Input
4
1 100 5 5
5
1 1 2
2 1 2
1 1 2
2 2 3
1 1 4
Sample Output
101
11
11
HINT
对于100%的数据, n ≤ 100000,m≤200000 ,data[i]非负且小于10^9
Source
与上帝造题的七分钟2有异曲同工之妙
不同的是上道题我用的是树状数组+并查集,这道是线段树
还是线段树好写
#include<cstdio>
#include<cmath>
#include<iostream>
#define ll long long
using namespace std;
inline int read()
{
char ch=getchar();
int ret=0;
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9')
ret=(ret<<1)+(ret<<3)+ch-'0',ch=getchar();
return ret;
}
int n,m;
const int N=1e5+5;
ll c[N<<2],a[N];
bool f[N<<2];
void build(int p,int l,int r)
{
if(l==r)
{
c[p]=a[l];
if(c[p]<=1) f[p]=1; return;
}
int mid=(l+r)>>1;
build(p+p,l,mid);
build(p+p+1,mid+1,r);
c[p]=c[p+p]+c[p+p+1];
f[p]=f[p+p]&f[p+p+1];
}
void add(int p,int l,int r,int x,int y)
{
if(f[p]) return;
if(l==r)
{
c[p]=(ll)sqrt(c[p]);
if(c[p]<=1) f[p]=1;
return;
}
int mid=(l+r)>>1;
if(y<=mid) add(p+p,l,mid,x,y);
else if(x>mid) add(p+p+1,mid+1,r,x,y);
else add(p+p,l,mid,x,mid),
add(p+p+1,mid+1,r,mid+1,y);
c[p]=c[p+p]+c[p+p+1];
f[p]=f[p+p]&f[p+p+1];
}
ll sum(int p,int l,int r,int x,int y)
{
if(l==x&&r==y) return c[p];
int mid=(l+r)>>1;
if(y<=mid) return sum(p+p,l,mid,x,y);
else if(x>mid) return sum(p+p+1,mid+1,r,x,y);
else return sum(p+p,l,mid,x,mid)+
sum(p+p+1,mid+1,r,mid+1,y);
}
int main()
{
n=read();
for(int i=1;i<=n;i++)
a[i]=read();
build(1,1,n);
m=read();
while(m--)
{
int t=read(),l=read(),r=read();
if(l>r) swap(l,r);
if(t==2) add(1,1,n,l,r);
else printf("%lld\n",sum(1,1,n,l,r));
}
return 0;
}