A Simple Problem with Integers

线段树大法好 splay码量太长了。

但是为了早日掌握splay,还是作死的写了一下

http://poj.org/problem?id=3468

就是线段树区间操作,lazy标记。只不过用splay实现。

写完之后发现,以前认为线段树代码量长,现在~~~~~~~

----------------------------树状数组更短-------------------------------

对比一下即可:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<cmath>
#include<algorithm>
using namespace std;
struct node
{long long l,r,sum,lazy;
}tree[800000+20];
long long n,q;
void build(long long i,long long l,long long r)
{tree[i].l=l;tree[i].r=r;tree[i].lazy=0;if(l==r){scanf("%lld",&tree[i].sum);return ;}long long mid=(l+r)/2;build(i*2,l,mid);build(i*2+1,mid+1,r);tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;}
void pushdown(long long i)
{if(!tree[i].lazy)return ;long long l=tree[i].l;long long r=tree[i].r;long long len=r-l+1;tree[i*2].lazy+=tree[i].lazy;tree[i*2+1].lazy+=tree[i].lazy;tree[i*2].sum+=tree[i].lazy*(len-len/2);tree[i*2+1].sum+=tree[i].lazy*(len/2);tree[i].lazy=0;
}
void add(long long i,long long a,long long b,long long x)
{long long l=tree[i].l;long long r=tree[i].r;if(l>=a&&r<=b){tree[i].sum+=x*(r-l+1);tree[i].lazy+=x;return ;}pushdown(i);long long mid=(l+r)>>1;if(a<=mid)add(i*2,a,b,x);if(b>mid)add(i*2+1,a,b,x);tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
}
long long query(long long i,long long a,long long b)
{long long l=tree[i].l;long long r=tree[i].r;if(l>=a&&r<=b)return tree[i].sum;pushdown(i);long long ans=0;long long mid=(l+r)/2;if(a<=mid)ans+=query(i*2,a,b);if(b>mid)ans+=query(i*2+1,a,b);return ans;
}
int main()
{scanf("%lld",&n);build(1,1,n);scanf("%lld",&q);for(long long i=1;i<=q;i++){long long f;scanf("%lld",&f);if(f==1){long long a,b,x;scanf("%lld%lld%lld",&a,&b,&x);add(1,a,b,x);}else if(f==2){long long a,b;scanf("%lld%lld",&a,&b);printf("%lld\n",query(1,a,b));}}return 0;
}

我写的结构体~

恩,挺长的。

但是

---------------------------------------------------------

---------------------------------------------------------

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<cmath>
#define maxn 100000+20
/*
bug数据
5 5
1 2 3 4 5
C 2 4 3
Q 4 5
(12)
*/
using namespace std;
long long ncnt=0;
struct node
{node *f;node *ch[2];long long sum,lazy,size,id;//分析一下我觉得需要记录这棵子树sum,lazy,这棵子树的size;//这个点的id (以便查询) 按id大小建树 node(){f=ch[0]=ch[1]=NULL;sum=lazy=size=0;}void zero(){f=ch[0]=ch[1]=NULL;sum=lazy=size=0;}
}S[maxn];
node *root;
long long n,q;
void pushdown(node *u)
{if(!u->lazy||u==NULL)return ;if(u->ch[0]!=NULL){u->ch[0]->lazy+=u->lazy;u->ch[0]->sum+=(u->ch[0]->size)*(u->lazy);}if(u->ch[1]!=NULL){u->ch[1]->lazy+=u->lazy;u->ch[1]->sum+=(u->ch[1]->size)*(u->lazy);}u->lazy=0;
}
void rotate(node *u)//把u旋到根
{node *f=u->f;if(f==NULL)return ;pushdown(f);pushdown(u);node *ff=f->f;long long d=u==f->ch[1];long long dd=0;if(ff!=NULL)dd=f==ff->ch[1];if(u->ch[d^1]!=NULL)u->ch[d^1]->f=f;f->ch[d]=u->ch[d^1]; long long size=u->size;u->size=f->size;f->size=f->size-size;if(u->ch[d^1]!=NULL)f->size+=u->ch[d^1]->size;//交换更新long long sum=u->sum;u->sum=f->sum;f->sum=f->sum-sum;if(u->ch[d^1]!=NULL)f->sum+=u->ch[d^1]->sum; u->ch[d^1]=f;f->f=u;if(ff!=NULL)ff->ch[dd]=u;u->f=ff;
}
void splay(node *u,node *p)
{pushdown(u);while(u->f!=p){node *f=u->f;node *ff=f->f;if(ff==p){rotate(u);break;}long long d=u==f->ch[1];long long dd=f==ff->ch[1];if(d==dd)rotate(f);else rotate(u);rotate(u);}if(p==NULL)root=u;
}
void insert(long long key,long long id)
{if(root==NULL){root=&S[++ncnt];root->f=NULL;root->id=id;root->sum=key;root->size=1;root->lazy=0;root->ch[0]=root->ch[1]=NULL;return ;}node *u=root;node *y;while(1){u->size+=1;u->sum+=key;if(id<u->id){if(u->ch[0]!=NULL)u=u->ch[0];else{y=&S[++ncnt];y->id=id;y->sum=key;y->lazy=0;y->size=1;y->ch[0]=y->ch[1]=NULL;y->f=u;u->ch[0]=y;break;}}else{if(u->ch[1]!=NULL)u=u->ch[1];else{y=&S[++ncnt];y->id=id;y->sum=key;y->lazy=0;y->size=1;y->ch[0]=y->ch[1]=NULL;y->f=u;u->ch[1]=y;break;}}}splay(y,NULL);
}
char s[5];
node *find(long long x)//id为x的位置
{node *u=root;while(1){pushdown(u);if(u->id==x)return u;if(x<u->id)u=u->ch[0];else u=u->ch[1];}
}
void add(long long l,long long r,long long v)
{//把l-1旋到根,把r+1选到根的右边,直接打上lazy标记就好了splay(find(l-1),NULL);splay(find(r+1),root);node *x=root->ch[1]->ch[0];x->lazy+=v;x->sum+=(x->size)*v; //更新父节点的值root->ch[1]->sum+=(x->size)*v;root->sum+=(x->size)*v;
}//忘记了更新父节点信息,草草草
long long query(long long l,long long r)
{splay(find(l-1),NULL);splay(find(r+1),root);return root->ch[1]->ch[0]->sum;
}
void dfs(node *u)//debug
{//printf("debug : id: %d sum: %d lazy: %d size: %d\n",u->id,u->sum,u->lazy,u->size);printf("%d  ",u->id);printf("lazy:%d  ",u->lazy );printf("size: %d ",u->size );printf("sum: %d\n",u->sum);if(u->ch[0])dfs(u->ch[0]);if(u->ch[1])dfs(u->ch[1]);
}
int main()
{while(scanf("%lld%lld",&n,&q)!=EOF){root=NULL;     ncnt=0;insert(0,0);insert(0,n+1);for(long long i=1;i<=n;i++){long long x;scanf("%lld",&x);           insert(x,i);}for(long long i=1;i<=q;i++){scanf("%s",s);if(s[0]=='C'){long long a,b,c;scanf("%lld%lld%lld",&a,&b,&c);                             add(a,b,c);}else{long long a,b;scanf("%lld%lld",&a,&b);printf("%lld\n",query(a,b));}}}return 0;
}

尼姆啊。

注:线段树的题是codevs1082的,操作类似,把Q,C改为1,2即可。

膜拜splay的码量。

然后,简述一下splay思路:

每次操作把l-1旋到根,r+1旋到根的下面, root->ch[1]->ch[0]就是[l,r]这一段区间。

然后当成线段树做就可以了(该修改的修改,该下放的下放)。

任何从上到下找的函数每一层都需要pushdown,道理同线段树。

splay真的是功能强大啊,但是代码量也太让人~~~

感人至深,splay的代码量相关推荐

  1. 12个常用的javascript简写技巧---可以大大减少js代码量

    微信公众号 个人博客 知乎 本文是并非本人所写,只是我看了觉得对自己很有帮助,所以分享给大家,原文链接在最下面,谢谢观看. 1. 空(null, undefined)验证 当我们创建了一个新的变量,我 ...

  2. 同一个内容,对比Java、C、PHP、Python的代码量,结局意外了

    为什么都说Python容易上手!是真的吗? 都说Python通俗易懂,容易上手,甚至不少网友表示「完成同一个任务,C 语言要写 1000 行代码,Java 只需要写 100 行,而 Python 可能 ...

  3. Java必会的工具库,让你的代码量减少90%

    以下文章来源方志朋的博客,回复"666"获面试宝典 工作很多年后,才发现有很多工具类库,可以大大简化代码量,提升开发效率,初级开发者却不知道.而这些类库早就成为了业界标准类库,大公 ...

  4. 世界上有哪些代码量很少,但很牛逼很经典的算法或项目案例?

    来自公众号:五分钟学算法 今天分享四个代码量很少,但很牛逼很经典的算法或项目案例. 1.no code 项目地址: https://github.com/kelseyhightower/nocode ...

  5. C#泛型简化代码量示例

    泛型简化代码量 下是我在项目中通过泛型来简化工作的一个Demo,记录一下: using System; using System.Collections.Generic; namespace MyCo ...

  6. 用StatSVN统计SVN服务器项目的代码量

    用StatSVN统计SVN服务器项目的代码量 下载并安装SVN统计工具StatSVN 1)下载地址:sourceforge.net/projects/statsvn/ 2)解压压缩包,到一个目录,如D ...

  7. WPF INotifyPropertyChanged 通过特性减少代码量

    在很多地方需要用上INotifyPropertyChanged的接口,MVVM模式,List等集合都会用到. 通常我们使用 protected void OnChange(PropertyChange ...

  8. cd返回上一 git_git统计代码量脚本

    在工作中,我想统计各开发人员,在一定日期范围内的编码情况,故有了此脚本. 一.先贴图,看看效果: 此图中,用"开发者姓名"代替了实际项目中git的账号名称,输出结果按提交次数倒序输 ...

  9. Git命令按人统计提交次数和代码量

    统计个人的代码量 git log --format='%aN' | sort -u | while read name; do echo -en "$name\t"; git lo ...

最新文章

  1. 第二十一课.粒子滤波器
  2. kindeditor扩展粘贴截图功能修改图片上传路径并通过webapi上传图片到图片服务器...
  3. [置顶] Android输入输出系统之TouchEvent流程
  4. java css隔行变色_JS+CSS实现Li列表隔行换色效果的方法
  5. 【网络流24题----01】飞行员配对方案问题
  6. 开了个会:破局企业云通信,华为加速 Buff 开发者!
  7. Linux Mint,Ubuntu 18 ,Deepin15.7 安装mysql 没有提示输入密码,修改root用户密码过程...
  8. gerber文件怎么导贴片坐标_如何学习贴片机编程
  9. 使用keras训练一个区分不同人声音的模型
  10. JavaScript open()
  11. Chrome插件:云音乐听歌识曲
  12. Win10安装cuda、cudnn检测是否安装成功
  13. S3C2440系统中断(转)
  14. kfc扫描点餐系统java_Java实现KFC点餐系统过程解析
  15. Deep C (and C++) by Olve Maudal and Jon Jagger
  16. photoshop学习之用钢笔工具抠图(循序渐进)
  17. pdf怎么压缩,好用的pdf压缩工具介绍
  18. TMS320F28377S 学习笔记1 GPIO及学习资料
  19. 锐捷无线地勘系统安装并新建项目(ChinaSkills国赛题解)
  20. 中国 GitHub 霸榜乱象! 真是把国内程序员的脸给丢尽了!

热门文章

  1. 怎么申请计算机软著?软件著作权申请难不难?没有鉴别材料怎么申请软著?
  2. Excel 透视表 - 人生第一个简单的透视表
  3. 阿里云Linux系统新手快速建站视频教程
  4. 计算机flash教案,认识Flash软件的教学设计
  5. VMware 如何通过现有虚拟机克隆新的虚拟机 (图文)
  6. vue + iview项目构建
  7. CSS_3th_div+CSS布局
  8. Docker Pull 下载镜像
  9. 第六届全国信息技术应用水平大赛Java组复赛B卷试题答案
  10. 攀枝花市2021年高考成绩查询,攀枝花第三高级中学2021年排名