题目描述
原题来自:BZOJ 3211
花神喜欢步行游历各国,顺便虐爆各地竞赛。花神有一条游览路线,它是线型的,也就是说,所有游历国家呈一条线的形状排列,花神对每个国家都有一个喜欢程度(当然花神并不一定喜欢所有国家)。
每一次旅行中,花神会选择一条旅游路线,它在那一串国家中是连续的一段,这次旅行带来的开心值是这些国家的喜欢度的总和,当然花神对这些国家的喜欢程序并不是恒定的,有时会突然对某些国家产生反感,使他对这些国家的喜欢度 δ\deltaδ 变为 δ\sqrt \delta√δ(可能是花神虐爆了那些国家的 OI,从而感到乏味)。
现在给出花神每次的旅行路线,以及开心度的变化,请求出花神每次旅行的开心值。
输入格式
第一行是一个整数 NNN,表示有 NNN 个国家;
第二行有 NNN 个空格隔开的整数,表示每个国家的初始喜欢度 δi\delta_iδi;
第三行是一个整数 MMM,表示有 MMM 条信息要处理;
第四行到最后,每行三个整数 x,l,rx,l,rx,l,r,当 x=1x=1x=1 时询问游历国家 lll 到 rrr 的开心值总和,也就是 ∑i=lrδi\sum\limits_{i=l}^r \delta_ii=l∑rδi ,当 x=2x=2x=2 时国家 lll 到 rrr 中每个国家的喜欢度 δi\delta_iδi 变为 δi\sqrt {\delta_i}√δi 。
输出格式
每次 x=1x=1x=1 时,每行一个整数。表示这次旅行的开心度。
样例
样例输入
4
1 100 5 5
5
1 1 2
2 1 2
1 1 2
2 2 3
1 1 4
样例输出
101
11
11
数据范围与提示
对于全部数据,1≤n≤105,1≤m≤2×105,1≤l≤r≤n,0≤δi≤1091\le n\le 10^5,1\le m\le 2\times 10^5,1\le l\le r\le n,0\le \delta_i \le 10^91≤n≤105,1≤m≤2×105,1≤l≤r≤n,0≤δi≤109。
注:建议使用 sqrt
函数,且向下取整。
开个ma[]维护最大值,如果为1或0,那么就不用修改了(我被100000个0卡了个点。。。这个0很重要!!!)
用sum[]维护区间和
自顶向下不过7次,每次更改维护至叶子结点。。。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; typedef long long ll; inline ll read() { ll res=0; char ch=0; while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9')res=(res<<3)+(res<<1)+ch-'0',ch=getchar(); return res; } int n,m; ll a[100001],sum[400001],ma[400001]; void build(int k,int l,int r) { if(l==r){sum[k]=ma[k]=a[l];return;} int mid=l+r>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); sum[k]=sum[k<<1]+sum[k<<1|1]; ma[k]=max(ma[k<<1],ma[k<<1|1]); } void modify(int k,int l,int r,int x,int y) { if(ma[k]==1||ma[k]==0)return; if(l==r){ma[k]=sum[k]=sqrt(sum[k]);return;} int mid=l+r>>1; if(x<=mid)modify(k<<1,l,mid,x,y); if(y>mid)modify(k<<1|1,mid+1,r,x,y); sum[k]=sum[k<<1]+sum[k<<1|1]; ma[k]=max(ma[k<<1],ma[k<<1|1]); } ll query(int k,int l,int r,int x,int y) { if(x<=l&&r<=y)return sum[k]; int mid=l+r>>1; ll res=0; if(x<=mid)res+=query(k<<1,l,mid,x,y); if(y>mid)res+=query(k<<1|1,mid+1,r,x,y); return res; } int main() { n=read(); for(int i=1;i<=n;++i)a[i]=read(); build(1,1,n); m=read(); while(m--) { int x=read(),y=read(),z=read(); if(x==1)printf("%lld\n",query(1,1,n,y,z)); else modify(1,1,n,y,z); } return 0; }