1550:花神游历各国
时间限制: 1000 ms 内存限制: 524288 KB
提交数: 127 通过数: 47
【题目描述】
原题来自:BZOJ 3211
花神喜欢步行游历各国,顺便虐爆各地竞赛。花神有一条游览路线,它是线型的,也就是说,所有游历国家呈一条线的形状排列,花神对每个国家都有一个喜欢程度(当然花神并不一定喜欢所有国家)。
每一次旅行中,花神会选择一条旅游路线,它在那一串国家中是连续的一段,这次旅行带来的开心值是这些国家的喜欢度的总和,当然花神对这些国家的喜欢程序并不是恒定的,有时会突然对某些国家产生反感,使他对这些国家的喜欢度 δ
变为 δ√
(可能是花神虐爆了那些国家的 OI,从而感到乏味)。
现在给出花神每次的旅行路线,以及开心度的变化,请求出花神每次旅行的开心值。
【输入】
第一行是一个整数 N,表示有 N个国家;
第二行有 N个空格隔开的整数,表示每个国家的初始喜欢度 δi;
第三行是一个整数 M,表示有 M条信息要处理;
第四行到最后,每行三个整数 x,l,r,当 x=1 时询问游历国家 l 到 r 的开心值总和,就是 ∑ri=lδi ,当 x=2 时国家 l 到 r 中每个国家的喜欢度 δi变为 δi−−√。
【输出】
每次 x=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≤109。
注:建议使用 sqrt
函数,且向下取整。
思路:
这个题是要求开方的,我们可以知道,一个数多开几次都会变成1,所以用flag标记,flag=1时表示不用开方了。
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<cmath>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef pair<int,int>P;
const int INF=4e8;
const int N=100015,mod=32767;
ll sum[N<<2];
int flag[N<<2];
void push_up(int rt){
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
flag[rt]=flag[rt<<1]&&flag[rt<<1|1];
}
void build(int l,int r,int rt){
if(l==r){
scanf("%lld",&sum[rt]);
if(sum[rt]<=1)flag[rt]=1;
return ;
}
int m=(r+l)>>1;
build(lson);
build(rson);
push_up(rt);
}
void push_down(int l,int r,int rt){
if(!flag[rt]){
if(l==r){
sum[rt]=floor(sqrt(sum[rt]));
if(sum[rt]<=1)flag[rt]=1;
return ;
}
int m=(l+r)>>1;
push_down(lson);
push_down(rson);
push_up(rt);
}
}
ll query(int L,int R,int l,int r,int rt){
if(L<=l&&R>=r){
return sum[rt];
}
int m=(l+r)>>1;
ll ans=0;
if(L<=m)ans+=query(L,R,lson);
if(R>m)ans+=query(L,R,rson);
return ans;
}
void update(int L,int R,int l,int r,int rt){
if(flag[rt])return ;
if(L<=l&&r<=R){
push_down(l,r,rt);
return ;
}
int m=(l+r)>>1;
if(L<=m)update(L,R,lson);
if(R>m)update(L,R,rson);
push_up(rt);
}
int main(){
int n,m,k,a,b;
scanf("%d",&n);
build(1,n,1);
scanf("%d",&m);
while(m--){
scanf("%d%d%d",&k,&a,&b);
if(k==1){
printf("%lld\n",query(a,b,1,n,1));
}
else{
update(a,b,1,n,1);
}
}
}