# bzoj3211 花神游历各国

4

1 100 5 5

5

1 1 2

2 1 2

1 1 2

2 2 3

1 1 4

101

11

11

## HINT

c++的除法是向下取整，很明显，(a+b)/k！=a/k+b/k（在向下取整的情况下），而根号，很明显根号（a）+根号(b)!=根号(a+b)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define MAXN 1000010
#define REP(i,k,n) for(int i=k;i<=n;i++)
using namespace std;
int x=0,f=1;
char ch=getchar();
for(;!isdigit(ch);ch=getchar())
if(ch=='-')
f=-1;
for(;isdigit(ch);ch=getchar())
x=x*10+ch-'0';
return x*f;
}
struct node{
int l,r;
long long lz,sum,maxx,minn;
}tree[MAXN<<2];
int n,m,input[MAXN];
inline void build(int i,int l,int r){
tree[i].l=l;tree[i].r=r;
if(l==r){
tree[i].sum=tree[i].minn=tree[i].maxx=input[l];
return ;
}
int mid=(l+r)>>1;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
tree[i].minn=min(tree[i*2].minn,tree[i*2+1].minn);
tree[i].maxx=max(tree[i*2].maxx,tree[i*2+1].maxx);
return ;
}
inline void push_down(int i){
if(!tree[i].lz)  return ;
long long k=tree[i].lz;
tree[i*2].lz+=k;
tree[i*2+1].lz+=k;
tree[i*2].sum-=(tree[i*2].r-tree[i*2].l+1)*k;
tree[i*2+1].sum-=(tree[i*2+1].r-tree[i*2+1].l+1)*k;
tree[i*2].minn-=k;
tree[i*2+1].minn-=k;
tree[i*2].maxx-=k;
tree[i*2+1].maxx-=k;
tree[i].lz=0;
return ;
}
inline void Sqrt(int i,int l,int r){
if(tree[i].l>=l && tree[i].r<=r && (tree[i].minn-(long long)sqrt(tree[i].minn))==(tree[i].maxx-(long long)sqrt(tree[i].maxx))){
long long u=tree[i].minn-(long long)sqrt(tree[i].minn);
tree[i].lz+=u;
tree[i].sum-=(tree[i].r-tree[i].l+1)*u;
tree[i].minn-=u;
tree[i].maxx-=u;
//cout<<"i"<<i<<" "<<tree[i].sum<<endl;
return ;
}
if(tree[i].r<l || tree[i].l>r)  return ;
push_down(i);
if(tree[i*2].r>=l)  Sqrt(i*2,l,r);
if(tree[i*2+1].l<=r)  Sqrt(i*2+1,l,r);
tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
tree[i].minn=min(tree[i*2].minn,tree[i*2+1].minn);
tree[i].maxx=max(tree[i*2].maxx,tree[i*2+1].maxx);
//cout<<"i"<<i<<" "<<tree[i].sum<<endl;
return ;
}
inline long long search(int i,int l,int r){
if(tree[i].l>=l && tree[i].r<=r)
return tree[i].sum;
if(tree[i].r<l || tree[i].l>r)  return 0;
push_down(i);
long long s=0;
if(tree[i*2].r>=l)  s+=search(i*2,l,r);
if(tree[i*2+1].l<=r)  s+=search(i*2+1,l,r);
return s;
}
int main(){
in(n);
REP(i,1,n)  in(input[i]);
build(1,1,n);
in(m);
int a,b,c;
REP(i,1,m){
in(a);in(b);in(c);
if(a==1)
printf("%lld\n",search(1,b,c));
if(a==2){
Sqrt(1,b,c);
//for(int i=1;i<=7;i++)
//    cout<<tree[i].sum<<" ";
// cout<<endl;
}
}
}

posted @ 2018-09-26 18:33  Dijkstra·Liu  阅读(135)  评论(0编辑  收藏  举报