codeforces 390E Inna and Large Sweet Matrix
2014-02-23 21:29
337 查看
本题的主要算法就是区间更新和区间求和;
可以用线段树和树状数组来做;
感觉线段树写的太麻烦了,看到官方题解上说可以用树状数组做,觉得很神奇,以前用过的树状数组都是单点维护,区间求和的;
其实树状数组还可以区间维护,单点求值;和区间维护,区间求和的;
详情请见博客。
View Code
可以用线段树和树状数组来做;
感觉线段树写的太麻烦了,看到官方题解上说可以用树状数组做,觉得很神奇,以前用过的树状数组都是单点维护,区间求和的;
其实树状数组还可以区间维护,单点求值;和区间维护,区间求和的;
详情请见博客。
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #define maxn 4000010 #define ll long long using namespace std; ll a[2][maxn]; ll b[2][maxn]; void add_a(int flag,int x,ll value) { while(x>0) { a[flag][x]+=value; x-=x&(-x); } } void add_b(int flag,int n,int x,ll value) { for(int i=x;i<=n;i+=i&(-i)) b[flag][i]+=x*value; } ll sum_a(int flag,int n,int x) { ll sum=0; while(x<=n) { sum+=a[flag][x]; x+=x&(-x); } return sum; } ll sum_b(int flag,int x) { ll sum=0; while(x>0) { sum+=b[flag][x]; x-=x&(-x); } return sum; } ll getsum(int flag,int n,int x) { if(x) return sum_a(flag,n,x)*x+sum_b(flag,x-1); else { return 0; } } int main() { int n,m,w; int comand; int x1,x2,y1,y2; int v; scanf("%d%d%d",&n,&m,&w); for(int i=0; i<w; i++) { scanf("%d",&comand); if(comand==0) { scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&v); ll vy=v*(y2-y1+1); ll vx=v*(x2-x1+1); add_a(0,x2,vy); add_b(0,n,x2,vy); if(x1>1) { add_a(0,x1-1,-vy); add_b(0,n,x1-1,-vy); } add_a(1,y2,vx); add_b(1,m,y2,vx); if(y1>1) { add_a(1,y1-1,-vx); add_b(1,m,y1-1,-vx); } } else { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); ll tmp1=getsum(0,n,x2)-getsum(0,n,x1-1); ll tmp2=getsum(1,m,y1-1); ll tmp3=getsum(1,m,m)-getsum(1,m,y2); cout<<tmp1-tmp2-tmp3<<endl; } } return 0; }
View Code
相关文章推荐
- Linux学习笔记(五)——Linux系统管理
- 开篇:序
- 开篇:序
- “阿里人”:企业文化与管理就是阿里巴巴的生命!
- Windows应用程序开发记录
- 题目1464:Hello World for U
- 开篇:序
- X宝外包软件测试工程师面试经历
- 电子类笔试题(包括模拟电路、IC基础、数字电路、微机)
- 《30天自制操作系统》学习笔记——第十一天
- bzoj 1833 [ZJOI2010] count 数字计数 题解
- VMWare下虚拟机ubuntu 和 windows文件共享
- 开篇:序
- 题目1202:排序
- 【Oracle】学习中所遇所学
- Codeforces 260D - Black and White Tree
- CSS学习拾遗
- Linux学习笔记(二)——文件、目录与磁盘格式
- 开篇:序
- ORACLE record is locked by another user?解锁