HDU 5454 Excited Database (2015年沈阳赛区网络赛E题)
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题)相关推荐
- hdu 5454 Excited Database(线段树)
题目链接:hdu 5454 Excited Database 解题思路 维护两科线段树,一棵i+j,一棵i-j.因为对角线上的值一定都是相同的,只是查询时的个数不一样,但是根据区间范围可以计算出来每条 ...
- ZOJ 3810 A Volcanic Island (2014年牡丹江赛区网络赛B题)
ZOJ 3810 A Volcanic Island (2014年牡丹江赛区网络赛B题) 1.题目描写叙述:点击打开链接 2.解题思路:本题是四色定理的模板题.只是有几种情况要提前特判一下:n==1直 ...
- HDU 5454 Excited Database 线段树的维护
传送门:HDU5454 Excited Database Time Limit: 1500/1000 MS (Java/Others) Memory Limit: 65535/102400 K ...
- HDU 5454 Excited Database【线段树】
简单线段树,就是推公式的过程有点不是特别熟练. 按照叉姐的方法,可以用三个树状数组维护,三种情况. 按照坦克工程师的方法,用容斥,将一个矩形分解成三个三角形,一个大的直角三角形减去两个小的直角三角形, ...
- hdu 4442 Physical Examination (2012年金华赛区现场赛A题)
昨天模拟赛的时候坑了好久,刚开始感觉是dp,仔细一看数据范围太大. 题目大意:一个人要参加考试,一共有n个科目,每个科目都有一个相应的队列,完成这门科目的总时间为a+b*(前面已完成科目所花的总时间) ...
- HDU - 5876 Sparse Graph 2016 ACM/ICPC 大连网络赛 I题 bfs+set+补图最短路
题目链接 题意:给的补图,让你求一个源点到其他点的最短距离,因为图太稠密了, 用dij以及spfa根本不得行,这里只能用一种我不会方法来进行,这里用了bfs的方法以及set来维护,分别set维护一个未 ...
- 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 ...
- 计蒜客-2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛H题Skiing(拓扑序求DAG最长路)
题意: 给定一个有向无环图,求该图的最长路. 思路: 由于是有向无环图,所以最长路肯定是一个入度为0到出度为0的路径,拓扑序在确定当前点之前能够考虑到所有到它的情况,所以最后取个最值即可. 代码: # ...
- 2017acm乌鲁木齐赛区网络赛F题tarjan缩点
poj1236是问把一棵树变成强联通分量,于是答案就是rudu为0的和出度为0的最大值,因为假设入度为0的多一些,先每个出度为0的连接一个入度为0的,那么还剩一些入度为0的,这时候入度为0的随意连接一 ...
最新文章
- Visual Studio 2010构建Web浏“.NET研究”览器应用程序
- nginx 修改html header,nginx 安全笔记 (修改nginx的header信息和错误显示版本号)
- 7 怎么查看文件夹容量_C盘(系统盘)磁盘剩余容量告警?如何解决与预防,C盘容量告急解决方法简单汇总!...
- 多项式拟合缺点_曲线拟合方法的选择
- nodejs 全局变量和全局对象
- Python 绘图库 Matplotlib
- 2020-10-13 四元数用法(不讲原理,只讲计算规则)
- C#的两种类据类型:值类型和引用类型
- Apache Ignite,Hazelcast,Cassandra和Tarantool之间的主要区别
- Python 如何利用函数修改函数外list?
- 【Android笔记】MediaPlayer基本用法
- 与计算机技术发展密切相关的科学家,关于计算机科学与技术的发展趋势探究
- RESTFfu l规范 以及理解
- 不知道怎么办了,犹豫中……
- 零拷贝的基本原理及使用Java通过零拷贝实现数据传输
- 微信小程序之上传图片功能
- SQL数据库置疑问题的处理方法
- 固网打印机服务器无线设置,通过设置连接打印机
- 计算机管理格式化硬盘,磁盘管理格式化硬盘出错的解决方法
- 海思HI3751_HMS开发指南