程序员人生 网站导航

【BZOJ3038】【Codevs2492】上帝造题的七分钟2

栏目:php教程时间:2015-04-29 07:43:56

脍炙人口双倍经验
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%的数据,1n,m1000,数列中的数不超过32767。
  对100%的数据,1n,m100000,1l,rn,数列中的数大于0,且不超过1e12。
  注意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); } }
------分隔线----------------------------
------分隔线----------------------------

最新技术推荐