1.题目描述:点击打开链接

2.解题思路:本题利用线段树解决,根据题意,我们需要建立两棵线段树,分别维护主对角线,副对角线。每个线段树的结点需要维护sum,sumL,sumR,其中,sum表示当前区间元素的和,sumL表示[L,R]这段区间中三角形和(第L层从1开始算)的值,sumR类似于sumL。查询时候把矩形看做一个平行四边形加上上下两个三角形来分3次查询。这样,本题即可在O(logN)时间内查询完毕。

3.代码:

#include<iostream>
#include<algorithm>
#include<cassert>
#include<string>
#include<sstream>
#include<set>
#include<bitset>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<cctype>
#include<complex>
#include<functional>
#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define rep(i,n) for(int i=0;i<(n);i++)
#define me(s) memset(s,0,sizeof(s))
#define pb push_back
#define lid (id<<1)
#define rid (id<<1|1)
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P;const int N=400000+5;
struct Node
{int l,r;ll sum;ll sumL,sumR;ll lazy;int length(){return r-l+1;}int mid(){return l+(r-l)/2;}void maintain(ll a){lazy+=a;sum+=a*length();ll add=a*(length()+1)*length()/2;sumL+=add;sumR+=add;}
};Node A[N<<2],D[N<<2];void pushup(Node*t,int id)
{t[id].sum=t[lid].sum+t[rid].sum;t[id].sumL=t[lid].sumL+t[rid].sumL+t[rid].sum*t[lid].length(); //大三角形=左儿子三角形+右儿子三角形+平行四边形t[id].sumR=t[lid].sumR+t[rid].sumR+t[lid].sum*t[rid].length();
}void pushdown(Node*t,int id)
{if(t[id].lazy){t[lid].maintain(t[id].lazy);t[rid].maintain(t[id].lazy);t[id].lazy=0;}
}void build(Node*t,int id,int L,int R)
{t[id].l=L,t[id].r=R;t[id].sum=t[id].sumL=t[id].sumR=t[id].lazy=0;if(L==R)return;int mid=t[id].mid();build(t,lid,L,mid);build(t,rid,mid+1,R);pushup(t,id);
}void update(Node*t,int id,int L,int R,int v)
{int l=t[id].l,r=t[id].r;if(L<=l&&r<=R){t[id].maintain(v);return;}pushdown(t,id);int mid=t[id].mid();if(L<=mid)update(t,lid,L,R,v);if(R>mid)update(t,rid,L,R,v);pushup(t,id);
}ll query(Node*t,int id,int L,int R)
{int l=t[id].l,r=t[id].r;if(L<=l&&r<=R) return t[id].sum;pushdown(t,id);int mid=t[id].mid();ll res=0;if(L<=mid)res+=query(t,lid,L,R);if(R>mid)res+=query(t,rid,L,R);pushup(t,id);return res;
}ll queryLeft(Node*t,int id,int L,int R)
{int l=t[id].l,r=t[id].r;if(L<=l&&r<=R)return t[id].sumL+t[id].sum*(l-L); //小三角形+平行四边形(平行四边形可能不存在)pushdown(t,id);int mid=t[id].mid();ll res=0;if(L<=mid)res+=queryLeft(t,lid,L,R);if(R>mid)res+=queryLeft(t,rid,L,R);pushup(t,id);return res;
}ll queryRight(Node*t,int id,int L,int R)
{int l=t[id].l,r=t[id].r;if(L<=l&&r<=R)return t[id].sumR+t[id].sum*(R-r);pushdown(t,id);int mid=t[id].mid();ll res=0;if(L<=mid)res+=queryRight(t,lid,L,R);if(R>mid)res+=queryRight(t,rid,L,R);pushup(t,id);return res;
}int n,q;int main()
{int T;int rnd=0;scanf("%d",&T);while(T--){printf("Case #%d:\n",++rnd);scanf("%d%d",&n,&q);build(A,1,2,2*n);build(D,1,1,2*n-1);int cmd;while(q--){scanf("%d",&cmd);int L,R;int x1,x2,y1,y2;if(cmd==1){scanf("%d%d",&L,&R);update(A,1,L,R,1);}if(cmd==2){scanf("%d%d",&L,&R);update(D,1,L+n,R+n,1);}if(cmd==3){scanf("%d%d%d%d",&x1,&x2,&y1,&y2);ll ans=0;ll num=min(x2-x1,y2-y1)+1;int l=x2+y1,r=x1+y2;if(l>r)swap(l,r);ans+=query(A,1,l,r)*num;ans+=queryLeft(A,1,x1+y1,l-1);ans+=queryRight(A,1,r+1,x2+y2);l=x1-y1+n,r=x2-y2+n;if(l>r)swap(l,r);ans+=query(D,1,l,r)*num;ans+=queryLeft(D,1,x1-y2+n,l-1);ans+=queryRight(D,1,r+1,x2-y1+n);printf("%lld\n",ans);}}}
}

HDU 5454 Excited Database (2015年沈阳赛区网络赛E题)相关推荐

  1. hdu 5454 Excited Database(线段树)

    题目链接:hdu 5454 Excited Database 解题思路 维护两科线段树,一棵i+j,一棵i-j.因为对角线上的值一定都是相同的,只是查询时的个数不一样,但是根据区间范围可以计算出来每条 ...

  2. ZOJ 3810 A Volcanic Island (2014年牡丹江赛区网络赛B题)

    ZOJ 3810 A Volcanic Island (2014年牡丹江赛区网络赛B题) 1.题目描写叙述:点击打开链接 2.解题思路:本题是四色定理的模板题.只是有几种情况要提前特判一下:n==1直 ...

  3. HDU 5454 Excited Database 线段树的维护

    传送门:HDU5454 Excited Database Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 65535/102400 K ...

  4. HDU 5454 Excited Database【线段树】

    简单线段树,就是推公式的过程有点不是特别熟练. 按照叉姐的方法,可以用三个树状数组维护,三种情况. 按照坦克工程师的方法,用容斥,将一个矩形分解成三个三角形,一个大的直角三角形减去两个小的直角三角形, ...

  5. hdu 4442 Physical Examination (2012年金华赛区现场赛A题)

    昨天模拟赛的时候坑了好久,刚开始感觉是dp,仔细一看数据范围太大. 题目大意:一个人要参加考试,一共有n个科目,每个科目都有一个相应的队列,完成这门科目的总时间为a+b*(前面已完成科目所花的总时间) ...

  6. HDU - 5876 Sparse Graph 2016 ACM/ICPC 大连网络赛 I题 bfs+set+补图最短路

    题目链接 题意:给的补图,让你求一个源点到其他点的最短距离,因为图太稠密了, 用dij以及spfa根本不得行,这里只能用一种我不会方法来进行,这里用了bfs的方法以及set来维护,分别set维护一个未 ...

  7. HDU - 5877 Weak Pair 2016 ACM/ICPC 大连网络赛 J题 dfs+树状数组+离散化

    题目链接 You are given a rootedrooted tree of NN nodes, labeled from 1 to NN. To the iith node a non-neg ...

  8. 计蒜客-2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛H题Skiing(拓扑序求DAG最长路)

    题意: 给定一个有向无环图,求该图的最长路. 思路: 由于是有向无环图,所以最长路肯定是一个入度为0到出度为0的路径,拓扑序在确定当前点之前能够考虑到所有到它的情况,所以最后取个最值即可. 代码: # ...

  9. 2017acm乌鲁木齐赛区网络赛F题tarjan缩点

    poj1236是问把一棵树变成强联通分量,于是答案就是rudu为0的和出度为0的最大值,因为假设入度为0的多一些,先每个出度为0的连接一个入度为0的,那么还剩一些入度为0的,这时候入度为0的随意连接一 ...

最新文章

  1. Visual Studio 2010构建Web浏“.NET研究”览器应用程序
  2. nginx 修改html header,nginx 安全笔记 (修改nginx的header信息和错误显示版本号)
  3. 7 怎么查看文件夹容量_C盘(系统盘)磁盘剩余容量告警?如何解决与预防,C盘容量告急解决方法简单汇总!...
  4. 多项式拟合缺点_曲线拟合方法的选择
  5. nodejs 全局变量和全局对象
  6. Python 绘图库 Matplotlib
  7. 2020-10-13 四元数用法(不讲原理,只讲计算规则)
  8. C#的两种类据类型:值类型和引用类型
  9. Apache Ignite,Hazelcast,Cassandra和Tarantool之间的主要区别
  10. Python 如何利用函数修改函数外list?
  11. 【Android笔记】MediaPlayer基本用法
  12. 与计算机技术发展密切相关的科学家,关于计算机科学与技术的发展趋势探究
  13. RESTFfu l规范 以及理解
  14. 不知道怎么办了,犹豫中……
  15. 零拷贝的基本原理及使用Java通过零拷贝实现数据传输
  16. 微信小程序之上传图片功能
  17. SQL数据库置疑问题的处理方法
  18. 固网打印机服务器无线设置,通过设置连接打印机
  19. 计算机管理格式化硬盘,磁盘管理格式化硬盘出错的解决方法
  20. 海思HI3751_HMS开发指南

热门文章

  1. Python数据结构与算法基础|第二期:代码实现——栈的顺序存储与链式存储
  2. SpringCloud之Eureka(微服务注册)
  3. MATLAB与ROS联合仿真(慕羽)虚拟机镜像文件使用方法
  4. MMA-Self-defining function
  5. 【转】英文论文审稿意见汇总
  6. 【Python】Python 仿真OFDM发射机、信道和接收机-实现多种调制方式
  7. 获取post中的请求参数1
  8. EventBus使用详解(二)——EventBus使用进阶
  9. 基于.NET平台常用的框架整理
  10. http协议学习系列