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 ...
随机推荐
- ASP.NET Zero--Migration控制台应用程序
Migration控制台应用程序 AspNet Zero包含一个工具Migrator.exe,用于轻松迁移数据库.您可以运行此应用程序来创建/迁移host和租户数据库. 该应用程序从它自己的appse ...
- php开发微信APP支付接口
之前在开发APP中用到了微信支付,因为是第一次用,所以中途也遇到了好多问题,通过查看文档和搜集资料,终于完成了该功能的实现.在这里简单分享一下后台php接口的开发实例. 原文地址:代码汇个人博客 ht ...
- mysql_报错1418
报错如下: 1418 - This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration a ...
- RabbitMQ集群搭建和使用
一.环境准备 1.选择RabbitMQ的版本 http://www.rabbitmq.com/changelog.html 注: 不同版本的Linux选择的RabbitMQ版本也不同,参照 http: ...
- KAPTCHA验证码使用步骤
使用kaptcha可以方便的配置: · 验证码的字体 · 验证码字体的大小 · 验证码字体的字体颜色 · 验证码内容的范围(数字,字母,中文汉字!) · 验证码图片的大小,边框,边框粗细,边框颜色 · ...
- 如何给python程序加密
在实际的工作中,有时候我们需要部署自己的Python应用,但这时候我们并不希望别人能够看到自己的Python源程序.因此,我们需要为自己的源代码进行加密,Python已经为我们提供了这样一套工作机制. ...
- springboot操作mongodb
springboot操作mongodb 采用MongoRepository操作mongodb springboot版本2.1.2.RELEASE 注意的是:在运行应用程序时,会报错OSS Algori ...
- golang 解析XML
用adb操控android手机时,可以解析页面控件信息(xml) 代码如下: package main import ( "encoding/xml" "fmt" ...
- Cursor: Pin S Wait On X In The Top 5 Wait Events
Wait Events , Posted in: Technical Track Tags: Group Blog Posts, Oracle, Technical Blog Lately, wait ...
- kubernetes1.14.0部署
2019/4/6/使用kubeadm安装部署kubernetes集群: 前提:1.各节点时间同步:2.各节点主机名称解析:dns OR hosts:3.各节点iptables及firewalld服务被 ...