【题】【线段树(不用lazy的区间修改)】NKOJ 2997 狗 【nodgd造水题】
来源:互联网 发布:iphone延时摄影软件 编辑:程序博客网 时间:2024/05/19 13:57
NKOJ 2997 狗 【nodgd造水题】
时间限制 : 6000 MS 空间限制 : 131072 KB
问题描述
nodgd家里有很多狗!太多的狗给nodgd带来了各种麻烦,于是nodgd决定开个赶走一些狗!
nodgd首先按照狗的品种把所有狗分成N类,依次是第1类,第2类,…,第N类。刚开始第i类有ai只。
nodgd有时候会心情不爽,就会把第l类、第l+1类、第l+2类、…、第r-1类、第r类的每类狗都进行这样的操作:
第一步,把这类狗排成一个尽量大的正方形方阵,多余的狗就赶走!
第二步,在正方形方阵中每一横排任选一条狗留下,其余全部赶走!
当然,狗也是需要喂食的,喂食之前需要先知道有多少条狗。因为赶走了一些狗,所以nodgd也记不清楚到底有多少条狗了,他可能会问你,第l类、第l+1类、第l+2类、…、第r-1类、第r类一共还剩多少条狗?你作为一个优秀的程序员,当然可以写个程序来回答nodgd的提问啦!
简化版题目描述:给个序列,区间开方,向下取整,区间求和。
输入格式
第一行两个整数N,M,分别表示狗的种类数和操作次数
第二行N个整数a1,a2,…,aN,表示每类狗一开始有多少条
接下来M行,每行三个整数k,l,r。若k=0则表示nodgd心情不爽了又要赶走一些狗了,若k=1则表示nodgd打算给狗喂食了就先向你提问
输出格式
对于nodgd的每次提问输出答案
样例输入
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
样例输出
19
7
6
提示
样例解释:
第一次操作之后狗的数量分别是1,1,1,2,2,2,2,2,3,3.
第四次操作之后狗的数量分别是1,1,1,2,1,1,1,1,3,3.
数据范围:
1<=N<=100000
1<=M<=100000
1<=ai<=1012
1<=l<=r<=N
来源 感谢nodgd抄袭别人的题目并提供数据
思路:
每次修改虽然是区间,但是每次一定要修改到叶节点,所以用不用lazy都差不多…..
结论:lazy使用条件:不知道子树信息也可以更新
注意开方很容易开成1,用1来“剪枝”。
#include<cstdio>#include<iostream>#include<cmath>using namespace std;#define ll long longconst int need=100003;struct fy{ll val;int a,b;}t[need<<1];int le[need<<1],ri[need<<1],tot=0;ll a[need];ll x,y;inline void in_(ll &d){ bool mark=false;char t=getchar(); while(t<'0'||t>'9'){if(t=='-') mark=true;t=getchar();} for(d=0;t>='0'&&t<='9';t=getchar())d=(d<<3)+(d<<1)-'0'+t; if(mark)d=-d;} char o[100];inline void out_(ll x){ int l=1; if(x<0) x=-x,putchar('-'); if(!x) putchar('0'); for(;x;x/=10) o[l++]=x%10+'0'; for(l--;l;l--)putchar(o[l]); putchar('\n'); } void build(int x,int y){ int s=++tot; t[s].a=x,t[s].b=y; if(x==y) { t[s].val=a[x]; return ; } le[s]=tot+1;build(x,(x+y)>>1); ri[s]=tot+1;build((x+y)/2+1,y); t[s].val=t[le[s]].val+t[ri[s]].val;} void modify(int s){ if(t[s].val==t[s].b-t[s].a+1) return ;//表示该区间所有狗都为1,修改后无变化。 if(t[s].a>y||t[s].b<x) return ; if(t[s].a==t[s].b) { t[s].val=t[s].val==1?1:floor(sqrt(t[s].val)); return ; } modify(le[s]),modify(ri[s]); t[s].val=t[le[s]].val+t[ri[s]].val;}ll getans(int s){ if(t[s].a>y||t[s].b<x) return 0; if(x<=t[s].a&&t[s].b<=y) return t[s].val; return getans(le[s])+getans(ri[s]);}int main(){ int n;scanf("%d",&n); for(int i=1;i<=n;i++) in_(a[i]);//scanf("%I64d",a[i]); build(1,n); int m;scanf("%d",&m); ll aa; for(int i=1;i<=m;i++) { in_(aa),in_(x),in_(y);//scanf("%d%d%d",&a,&x,&y); if(aa==0) modify(1); else out_(getans(1));//printf("%I64d",getans(1)); }}
- 【题】【线段树(不用lazy的区间修改)】NKOJ 2997 狗 【nodgd造水题】
- 区间修改lazy线段树
- 【题】【线段树(区间·LAZY)】NKOJ 1550 旅馆 【Usaco Feb08 Gold】
- SKYLINE uva+线段树+区间的修改+lazy标记
- 线段树区间修改 lazy标记 大法
- 线段树2(区间修改,lazy)
- 线段树——区间修改(Lazy-Tag)
- NKOJ 4254 区间MEX (线段树)
- 【题】【线段树(lazy)】NKOJ 1868 矩形周长【USACO5.5.1】Picture
- 线段树的区间修改
- coj 1123 带区间操作的线段树(lazy)
- hdu-4587-线段树的区间操作- lazy标记
- hdoj 1698 Just a Hook 【线段树 区间修改】【线段树 + lazy思想】
- POJ2777(线段树区间更新+LAZY)
- poj 3468 线段树区间更新lazy
- 线段树区间修改之双标记 【lazy两重标记并且分类讨论】
- 线段树区间修改
- 线段树区间修改
- 过渡
- 动画
- 和尚练猪练丹经验贴——从入门到精通
- 【学习笔记】Android-打造炫酷进度条(条形)
- Bootstrap
- 【题】【线段树(不用lazy的区间修改)】NKOJ 2997 狗 【nodgd造水题】
- JAVA面向对象-----接口的特点
- APK 去广告(修改代码级)
- C++类和new、delete操作符和堆和栈内存的分配
- JAVA面向对象-----接口与类、接口之间的关系
- FastDFS特性及问题思考
- 深入浅出 消息队列 ActiveMQ
- 在Qt中读写INI配置文件
- 有 Return 的情况下 Try Catch Finally的执行顺序(详细的代码以及解释)