POJ 3468 线段树+状压
2016-06-29 19:42
281 查看
题意:给你n个数,有对区间的加减操作,问某个区间的和是多少。
思路:状压+线段树(要用lazy标记,否则会TLE)
//By SiriusRen #include <cstdio> #include <cstring> #define N 100001 using namespace std; long long tree[N*4],lazy[N*4]; int xx,yy,zz,n,q; char jy; void push_down(int pos,int num){ lazy[pos*2]+=lazy[pos],lazy[pos*2+1]+=lazy[pos]; tree[pos*2]+=(num-num/2)*lazy[pos],tree[pos*2+1]+=(num/2)*lazy[pos]; lazy[pos]=0; } void build(int l,int r,int pos){ if(l==r){scanf("%lld",&tree[pos]);return;} int mid=(l+r)/2; build(l,mid,pos*2),build(mid+1,r,pos*2+1); tree[pos]=tree[pos*2]+tree[pos*2+1]; } void add(int l,int r,int pos){ if(l>=xx&&r<=yy){lazy[pos]+=zz;tree[pos]+=(long long)(r-l+1)*zz;return;} if(lazy[pos])push_down(pos,r-l+1); int mid=(l+r)/2; if(mid>=xx)add(l,mid,pos*2); if(mid<yy)add(mid+1,r,pos*2+1); tree[pos]=tree[pos*2]+tree[pos*2+1]; } long long query(int l,int r,int pos){ if(l>=xx&&r<=yy)return tree[pos]; if(lazy[pos])push_down(pos,r-l+1); int mid=(l+r)/2; if(mid<xx)return query(mid+1,r,pos*2+1); else if(mid>=yy)return query(l,mid,pos*2); else return query(l,mid,pos*2)+query(mid+1,r,pos*2+1); } int main(){ scanf("%d%d",&n,&q); build(1,n,1); while(q--){ scanf("\n%c%d%d",&jy,&xx,&yy); if(jy=='C')scanf("%d",&zz),add(1,n,1); else printf("%lld\n",query(1,n,1)); } }
相关文章推荐
- window平台安装 MongoDB
- 如何在 Linux 中统计一个进程的线程数
- 协作
- QML中MouseArea元素的介绍
- 【NOIP2013模拟】期望异或&&【NOI2015模拟9.7】大新闻
- 4-7 统计某类完全平方数 (20分)
- 解析xml文件的几种技术与Dom4j与sax之间的对比
- ASP.NET中Session的sessionState 4种mode模式
- linux下查看线程数的几种方法
- 远程代码注入
- Javascript基础入门
- 有一种生物叫做程序员。。。。
- UVa 11212 Editing a Book (编辑书稿)迭代加深
- 测测
- 易宝典文章——玩转Office 365中的Exchange Online服务 之二十三 实现基于IP地址的邮件过滤
- pci option rom 加载过程
- timeline自适应时间轴
- UVA-11212 Editing a Book (IDA*)
- 测试测试
- 《深入探索C++对象模型》第三章奇怪语句解释