【UOJ228】基础数据结构练习题(线段树)
来源:互联网 发布:淘宝店铺主页封面 编辑:程序博客网 时间:2024/05/18 03:25
Description
sylvia 是一个热爱学习的女孩子,今天她想要学习数据结构技巧。
在看了一些博客学了一些姿势后,她想要找一些数据结构题来练练手。于是她的好朋友九条可怜酱给她出了一道题。
给出一个长度为 nn 的数列 AA,接下来有 mm 次操作,操作有三种:
对于所有的 i∈[l,r]i∈[l,r],将 Ai变成 Ai+x。对于所有的 i∈[l,r]i∈[l,r],将 Ai变成 ⌊√Ai⌋。对于所有的 i∈[l,r]i∈[l,r],询问 Ai的和。
作为一个不怎么熟练的初学者,sylvia 想了好久都没做出来。而可怜酱又外出旅游去了,一时间联系不上。于是她决定向你寻求帮助:你能帮她解决这个问题吗。
Input
第一行两个数:n,m。
接下来一行 n个数 Ai。
接下来 m行中,第 i 行第一个数
若
若
若
Output
对于每个询问操作,输出一行表示答案。
Sample Input
5 51 2 3 4 51 3 5 22 1 43 2 42 3 53 1 5
Sample Output
56
Data
对于所有数据,保证有
I think
我们来搞第二个操作。
单点修改变成 ⌊√Ai⌋是会TLE的。但是对于每一个数n,同样可以在近
我们维护区间最大最小值mx[i],mn[i],当一个区间满足
这个区间内的每个元素开根号之后的变化量相同,于是我们就可以很方便地更新了。
在传递添加值x时,尽管
*1ll
避免溢出。Code
#include<cmath>#include<cstdio>using namespace std;const int sm = 8e5+50;typedef long long LL;int v,n,m;LL s[sm],a[sm],mx[sm],mn[sm];char ch;template <typename T> T Max(T x,T y) { return x>y?x:y; }template <typename T> T Min(T x,T y) { return x<y?x:y; } template <typename T> void read(T &x) { x=0,ch=getchar(); while(ch>'9'||ch<'0') ch=getchar(); while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();}void update(int i) { s[i]=s[i<<1]+s[i<<1|1]; mx[i]=Max(mx[i<<1],mx[i<<1|1]); mn[i]=Min(mn[i<<1],mn[i<<1|1]);}void pd(int i,int l,int r) { int ls=i<<1,rs=i<<1|1,m=(r+l)>>1; a[ls]+=a[i],a[rs]+=a[i]; s[ls]+=(m-l+1)*a[i],s[rs]+=(r-m)*a[i]; mx[ls]+=a[i],mn[ls]+=a[i]; mx[rs]+=a[i],mn[rs]+=a[i]; a[i]=0;}void build(int i,int l,int r) { if(l==r) { read(v),s[i]=mx[i]=mn[i]=v; return ; } int m=(l+r)>>1; build(i<<1,l,m); build(i<<1|1,m+1,r); update(i);}void add(int i,int l,int r,int ll,int rr,int val) {// if(ll<=l&&r<=rr) { a[i]=1ll*(a[i]+val),s[i]=s[i]+1ll*(r-l+1)*val; mx[i]=1ll*(mx[i]+val),mn[i]=1ll*(mn[i]+val); return ; } if(a[i])pd(i,l,r); int m=(l+r)>>1; if(ll<=m) add(i<<1,l,m,ll,rr,val); if(rr> m) add(i<<1|1,m+1,r,ll,rr,val); update(i);}bool chk(int i) { return (mx[i]==mn[i])||(mx[i]-mn[i]==floor(sqrt(mx[i]))-floor(sqrt(mn[i])));}void modify(int i,int l, int r,int ll,int rr) { if(ll<=l&&r<=rr&&chk(i)) { LL d=floor(sqrt(mx[i]))-mx[i]; mx[i]+=d,mn[i]+=d; a[i]+=d,s[i]+=(r-l+1)*d; return; } if(a[i])pd(i,l,r); int m=(l+r)>>1; if(ll<=m) modify(i<<1,l,m,ll,rr); if(rr> m) modify(i<<1|1,m+1,r,ll,rr); update(i);}LL query(int i,int l,int r,int ll,int rr) { if(ll<=l&&r<=rr) return s[i]; if(a[i])pd(i,l,r); int m=(l+r)>>1;LL ans=0; if(ll<=m) ans+=query(i<<1,l,m,ll,rr); if(rr> m) ans+=query(i<<1|1,m+1,r,ll,rr); update(i); return ans;}int main() { read(n),read(m); build(1,1,n); int ind,l,r,x; for(LL i=1;i<=m;++i) { read(ind),read(l),read(r); if(ind==1) read(x),add(1,1,n,l,r,x); else if(ind==2) modify(1,1,n,l,r); else printf("%lld\n",query(1,1,n,l,r)); } return 0;}
阅读全文
0 0
- 【UOJ228】基础数据结构练习题(线段树)
- [题解]uoj228 基础数据结构练习题
- [uoj228]基础数据结构练习题 解题报告
- [均摊 线段树] UOJ #228. 基础数据结构练习题
- [均摊 线段树] UOJ#228. 基础数据结构练习题
- 【线段树+均摊思想】UOJ #228 基础数据结构练习题
- 【数据结构基础]】数据库练习题
- 线段树练习题一
- 线段树练习题一
- 线段树练习题二
- 线段树练习题三
- 线段树练习题三
- UOJ#228 基础数据结构练习题
- uoj#228. 基础数据结构练习题
- [UOJ#228]基础数据结构练习题
- UOJ 228 基础数据结构练习题
- 【UOJ #228】 基础数据结构练习题
- 数据结构_线段树_基础模板
- July Challenge 2017 | Calculator
- JAVA-1007. 素数对猜想 (20)
- cf #422 c Hacker, pack your bags! 【贪心】
- SQL Server CONVERT() 函数
- 【原创】ARM串口控制台
- 【UOJ228】基础数据结构练习题(线段树)
- Web自动化之Headless Chrome测试框架集成
- 记一次失败的小米面试
- AsyncTask简单的用法 点击加载图片
- leetcode 381. Insert Delete GetRandom O(1)
- 【面经笔记】红黑树的特性与其在C++ STL中的应用
- hdu 5831 Rikka with Parenthesis II
- 队列
- splay_tree