脍炙人口双倍经验
2492 上帝造题的7分钟 2
时间限制: 1 s
空间限制: 64000 KB
题目等级 : 大师 Master
题目描写 Description
XLk觉得《上帝造题的7分钟》不太过瘾,因而有了第2部。
“第1分钟,X说,要有数列,因而便给定了1个正整数数列。
第2分钟,L说,要能修改,因而便有了对1段数中每一个数都开平方(下取整)的操作。
第3分钟,k说,要能查询,因而便有了求1段数的和的操作。
第4分钟,彩虹喵说,要是noip难度,因而便有了数据范围。
第5分钟,诗人说,要有韵律,因而便有了时间限制和内存限制。
第6分钟,和雪说,要省点事,因而便有了保证运算进程中及终究结果均不超过64位有符号整数类型的表示范围的限制。
第7分钟,这道题终究造完了,但是,造题的神牛们不再想写这道题的程序了。”
――《上帝造题的7分钟・第2部》
所以这个神圣的任务就交给你了。
输入描写 Input Description
第1行1个整数n,代表数列中数的个数。
第2行n个正整数,表示初始状态下数列中的数。
第3行1个整数m,表示有m次操作。
接下来m行每行3个整数k,l,r,k=0表示给[l,r]中的每一个数开平方(下取整),k=1表示询问[l,r]中各个数的和。
UPD:注意数据中有可能l>r,所以遇到这类情况请交换l和r。
输出描写 Output Description
对询问操作,每行输出1个回答。
样例输入 Sample Input
10
1 2 3 4 5 6 7 8 9 10
5
0 1 10
1 1 10
1 1 5
0 5 8
1 4 8
样例输出 Sample Output
19
7
6
数据范围及提示 Data Size & Hint
对30%的数据,1
对100%的数据,1
注意l有可能大于r,遇到这类情况请交换l,r。
来源:Nescafe 20
和花神游历各国完全1样233
直接代码(其实再发这篇我是为了访问量和经验)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAXN 100100
#define MAXM 201000
#define lchild rt<<1,l,mid
#define rchild rt<<1|1,mid+1,r
#define ln rt<<1
#define rn rt<<1|1
using namespace std;
struct seg
{
int l,r;
long long sum,maxn;
}tree[MAXN<<4];
int n,m;
int op,l,r;
void push_up(int rt)
{
tree[rt].sum=tree[ln].sum+tree[rn].sum;
tree[rt].maxn=max(tree[ln].maxn,tree[rn].maxn);
}
void build(int rt=1,int l=1,int r=n)
{
int mid=(l+r)>>1;
tree[rt].l=l;tree[rt].r=r;
if (l==r)
{
scanf("%lld",&tree[rt].sum);
tree[rt].maxn=tree[rt].sum;
return;
}
build(lchild);build(rchild);
push_up(rt);
}
void modify(int rt,int l,int r)
{
if (tree[rt].maxn<=1) return;
int L=tree[rt].l,R=tree[rt].r,mid=(L+R)>>1;
if (L==R)
{
tree[rt].sum=floor(sqrt(tree[rt].sum));
tree[rt].maxn=tree[rt].sum;
return;
}
if (l<=mid) modify(ln,l,r);
if (r>mid) modify(rn,l,r);
push_up(rt);
}
long long query(int rt,int l,int r)
{
int L=tree[rt].l,R=tree[rt].r,mid=(L+R)>>1;
if (L==l&&R==r) return tree[rt].sum;
if (r<=mid) return query(ln,l,r);
else
if (l>mid) return query(rn,l,r);
else return query(ln,l,mid)+query(rn,mid+1,r);
}
int main()
{
scanf("%d",&n);
build();
scanf("%d",&m);
for (int i=1;i<=m;i++)
{
scanf("%d%d%d",&op,&l,&r);
if (l>r) swap(l,r);
if (op==1)
printf("%lld
",query(1,l,r));
else
modify(1,l,r);
}
}