Stanford Local 2016 G "Ground Defense"(线段树)
题意:
有 n 个城市,编号 1~n;
有两种操作:Update,Query
Update:
E i s a d
更新区间[ i,i+d-1 ], i 节点降落 s 人, i+1 节点降落 s+a 人, i+2 节点降落 s+2*a 人,......, i+d-1 节点降落 s+(d-1)*a 人;
W i s a d
更新区间[ i-d+1,i ], i 节点降落 s 人, i-1 节点降落 s+a 人, i-2 节点降落 s+2*a 人,......, i-d+1 节点降落 s+(d-1)*a 人;
简言之,从 i 节点下降 s 人开始,向东(右),西(左)下降的人数依次 +a;
Query: i
查询在节点 i 降落的总人数。
题解:
看到这道题,第一反应是线段树区间更新,那具体怎么个更新法呢?
首先看线段树中定义的元素:
struct SegmentTree
{
int l,r;
ll s;//l处增加s人
ll a;//从l到r依次变化a人
int mid()
{
return l+((r-l)>>);
}
}segTree[*maxn];
定义Update()函数,具体如下:
void Update(int l,int r,int pos,ll s,ll a)
{
if(segTree[pos].l == l && segTree[pos].r == r)
{
segTree[pos].s += s;//pos节点中的s增加s
segTree[pos].a += a;//pos节点中的a增加a
return ;
}
pushDown(pos);//向下更新 int mid=segTree[pos].mid();
if(r <= mid)
Update(l,r,ls(pos),s,a);
else if(l > mid)
Update(l,r,rs(pos),s,a);
else
{
ll d=mid+-l;
Update(l,mid,ls(pos),s,a);
Update(mid+,r,rs(pos),s+d*a,a);//注意右儿子更新的s值
}
}
如果更新操作为 E i s a d :
调用函数 Update( i , i+d-1 , 1 , s , a );
反之,如果更新操作为 W i s a d ⇔ E (i-d+1) ( s+(d-1)*a ) (-a) d
调用函数 Update( (i-d+1) , i , 1 , s+(d-1)*a , -a );
更新函数中的pushDown()函数是非常重要的,其决定了此算法的正确与否:
//将pos节点更新的状态传给儿子节点
void pushDown(int pos)
{
ll &s=segTree[pos].s;
ll &a=segTree[pos].a;
if(s)//如果s不为0,说明在这之前曾更新过pos节点
{
//左儿子的更新
segTree[ls(pos)].s += s;
segTree[ls(pos)].a += a; /**
右儿子的更新操作
注意 segTree[rs(pos)].s 增加的值
具体原因留给读者自己思索
*/
segTree[rs(pos)].s += s+a*(segTree[rs(pos)].l-segTree[ls(pos)].l);
segTree[rs(pos)].a += a;
}
s=;
a=;
}
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
const int maxn=5e5+; int n,m;
struct SegmentTree
{
int l,r;
ll s;//l处增加s人
ll a;//从l到r依次增加a
int mid()
{
return l+((r-l)>>);
}
}segTree[*maxn]; void pushDown(int pos)
{
ll &s=segTree[pos].s;
ll &a=segTree[pos].a;
if(s)
{
segTree[ls(pos)].s += s;
segTree[ls(pos)].a += a; /**
右儿子的更新操作
注意 segTree[rs(pos)].s 增加的值
具体原因留给读者自己思索
*/
segTree[rs(pos)].s += s+a*(segTree[rs(pos)].l-segTree[ls(pos)].l);
segTree[rs(pos)].a += a;
}
s=;
a=;
}
void buildSegTree(int l,int r,int pos)
{
segTree[pos].l=l;
segTree[pos].r=r;
segTree[pos].s=;
segTree[pos].a=;
if(l == r)
return ; int mid=l+((r-l)>>);
buildSegTree(l,mid,ls(pos));
buildSegTree(mid+,r,rs(pos));
}
void Update(int l,int r,int pos,ll s,ll a)
{
if(segTree[pos].l == l && segTree[pos].r == r)
{
segTree[pos].s += s;
segTree[pos].a += a;
return ;
}
pushDown(pos);//向下更新 int mid=segTree[pos].mid();
if(r <= mid)
Update(l,r,ls(pos),s,a);
else if(l > mid)
Update(l,r,rs(pos),s,a);
else
{
ll d=mid+-l;
Update(l,mid,ls(pos),s,a);
Update(mid+,r,rs(pos),s+d*a,a);//注意右儿子更新的s值
}
}
ll Query(int x,int pos)
{
if(segTree[pos].l == segTree[pos].r)
return segTree[pos].s;
pushDown(pos); int mid=segTree[pos].mid();
if(x <= mid)
return Query(x,ls(pos));
else
return Query(x,rs(pos));
}
int main()
{
// freopen("C:\\Users\\hyacinthLJP\\Desktop\\in&&out\\contest","r",stdin);
int test;
scanf("%d",&test);
while(test--)
{
scanf("%d%d",&m,&n);
buildSegTree(,n,);
while(m--)
{
char order[];
scanf("%s",order);
if(order[] == 'U')
{
char x[];
int i,s,a,d;
scanf("%s%d%d%d%d",x,&i,&s,&a,&d);
if(x[] == 'E')
{
//r=min()是为了防止数据出错使得 i+d-1 > n
int r=min(n,i+d-);
Update(i,r,,s,a);
}
else
{
//l=max()是为了防止数据出错使得 i-d+1 < 1
int l=max(,i-d+);
Update(l,i,,1ll*s+1ll*a*(d-),-a);
}
}
else
{
int i;
scanf("%d",&i);
printf("%lld\n",Query(i,));
}
}
}
return ;
}
Stanford Local 2016 G "Ground Defense"(线段树)的更多相关文章
- BZOJ_4276_[ONTAK2015]Bajtman i Okrągły Robin_线段树优化建图+最大费用最大流
BZOJ_4276_[ONTAK2015]Bajtman i Okrągły Robin_线段树优化建图+最大费用最大流 Description 有n个强盗,其中第i个强盗会在[a[i],a[i]+1 ...
- BZOJ 4276: [ONTAK2015]Bajtman i Okrągły Robin [线段树优化建边]
4276: [ONTAK2015]Bajtman i Okrągły Robin 题意:\(n \le 5000\)个区间\(l,r\le 5000\),每个区间可以选一个点得到val[i]的价值,每 ...
- Educational Codeforces Round 51 (Rated for Div. 2) G. Distinctification(线段树合并 + 并查集)
题意 给出一个长度为 \(n\) 序列 , 每个位置有 \(a_i , b_i\) 两个参数 , \(b_i\) 互不相同 ,你可以进行任意次如下的两种操作 : 若存在 \(j \not = i\) ...
- 【BZOJ4276】[ONTAK2015]Bajtman i Okrągły Robin 线段树优化建图+费用流
[BZOJ4276][ONTAK2015]Bajtman i Okrągły Robin Description 有n个强盗,其中第i个强盗会在[a[i],a[i]+1],[a[i]+1,a[i]+2 ...
- codeforces 626 G. Raffles(线段树+思维+贪心)
题目链接:http://codeforces.com/contest/626/problem/G 题解:这题很明显买彩票肯定要买贡献最大的也就是说买p[i]*(num[i]+1)/(num[i]+a[ ...
- LYOI 2016 Summer 函数 【线段树】
<题目链接> 题目大意: fqk 退役后开始补习文化课啦,于是他打开了数学必修一开始复习函数,他回想起了一次函数都是 f(x)=kx+b的形式,现在他给了你n个一次函数 fi(x)=kix ...
- ACM-ICPC 2018 徐州赛区网络预赛-G Trace(线段树的应用
Problem:Portal传送门 Problem:Portal传送门 原题目描述在最下面. 我理解的题意大概是:有n次涨潮和退潮,每次的范围是个x×y的矩形,求n次涨退潮后,潮水痕迹的长度. ...
- Stanford Local 2016 E "Election of Evil"(搜索(正解)或并查集(划掉))
传送门 题意: 给出集合U,V,集合U有n个元素,集合V有m个元素: 有 m 个操作,mi : s1 s2 有一条s1指向s2的边(s1,s2可能属于第三个集合,暂且称之为K集合): 指向边具有传递性 ...
- 华中农业大学第四届程序设计大赛网络同步赛 G.Array C 线段树或者优先队列
Problem G: Array C Time Limit: 1 Sec Memory Limit: 128 MB Description Giving two integers and and ...
随机推荐
- window下 mongodb快速安装
下载地址 https://www.mongodb.org/dl/win32/x86_64-2008plus-ssl 建立文件夹和文件 #数据库路径 dbpath=G:\mongodb3.4.12\da ...
- Page Cache与Page回写
综述 Page cache是通过将磁盘中的数据缓存到内存中,从而减少磁盘I/O操作,从而提高性能.此外,还要确保在page cache中的数据更改时能够被同步到磁盘上,后者被称为page回写(page ...
- 启动期间的内存管理之bootmem_init初始化内存管理–Linux内存管理(十二)
1. 启动过程中的内存初始化 首先我们来看看start_kernel是如何初始化系统的, start_kerne定义在init/main.c?v=4.7, line 479 其代码很复杂, 我们只截取 ...
- Angular安装及创建第一个项目
Angular简介 AngularJS 诞生于2009年,由Misko Hevery 等人创建,后为Google所收购.是一款优秀的前端JS框架,已经被用于Google的多款产品当中.AngularJ ...
- gradlew和gradle的区别
概念理解 gradlew就是对gradle的包装和配置,gradlew是gradle Wrapper,Wrapper的意思就是包装. 因为不是每个人的电脑中都安装了gradle,也不一定安装的版本是要 ...
- Arduino 串口测试 电脑发数据接收后立马返回
String comdata = ""; void setup() { Serial.begin(9600); while(Serial.read()>= 0){} //cl ...
- Chrome Inspect调试微信出现404,需要FQ
要么FQ,要么买个程序 见连接 http://www.cnblogs.com/slmk/p/7591126.html
- wps for linux显示系统缺失字体解决办法
1.下载字体库 链接: https://pan.baidu.com/s/1xil5_i9M53fM7EQNIt3Mcw 密码: jqnu 2.解压 sudo unzip wps_symbol_font ...
- Linux内存管理 (9)mmap
专题:Linux内存管理专题 关键词:文件映射.匿名映射.私有映射.共享映射 mmap/munmap是常用的一个系统调用,使用场景是:分配内存.读写大文件.连接动态库文件.多进程间共享内存. 更详细解 ...
- 在 .NET Core 中结合 HttpClientFactory 使用 Polly(中篇)
译者:王亮作者:Polly 团队原文:http://t.cn/EhZ90oq声明:我翻译技术文章不是逐句翻译的,而是根据我自己的理解来表述的(包括标题).其中可能会去除一些不影响理解但本人实在不知道如 ...