Training address: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=38994#overview

B.Xenia and Bit Operations ----Codeforces 339D

线段树大水题。。每个节点维护一个flag,flag=1表示此时应与其兄弟节点做或(|)操作,flag=2表示做异或(^)操作,然后pushup...

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define N 140010 struct node
{
int sum,flag;
}tree[*N]; int two_n(int mi)
{
int i;
int res = ;
for(i=;i<=mi;i++)
{
res *= ;
}
return res;
} int a[N]; void pushup(int rt)
{
if(tree[*rt].flag == )
{
tree[rt].sum = tree[*rt].sum | tree[*rt+].sum;
tree[rt].flag = ;
}
else
{
tree[rt].sum = tree[*rt].sum ^ tree[*rt+].sum;
tree[rt].flag = ;
}
} void build(int l,int r,int rt)
{
if(l == r)
{
tree[rt].sum = a[l];
tree[rt].flag = ;
return;
}
int mid = (l+r)/;
build(l,mid,*rt);
build(mid+,r,*rt+);
pushup(rt);
} void update(int l,int r,int pos,int val,int rt)
{
if(l == r)
{
tree[rt].sum = val;
tree[rt].flag = ;
return;
}
int mid = (l+r)/;
if(pos<=mid)
update(l,mid,pos,val,*rt);
else
update(mid+,r,pos,val,*rt+);
pushup(rt);
} int main()
{
int n,m;
int i,pos,val;
while(scanf("%d%d",&n,&m)!=EOF)
{
int ken = two_n(n);
for(i=;i<=ken;i++)
{
scanf("%d",&a[i]);
}
build(,ken,);
for(i=;i<m;i++)
{
scanf("%d%d",&pos,&val);
update(,ken,pos,val,);
printf("%d\n",tree[].sum);
}
}
return ;
}

D.Copying Data ----Codeforces 292E

这题初看像线段树题,结果就是线段树题。怎么做树,维护哪些值呢? 开始想歪了,参照了别人的报告,于是知道,可以维护stx,sty值,这些值只在叶子节点上表现出来,因为只查叶子节点,不查区间,stx记录这个节点有没有被copy成a数组中的元素,stx == 0则代表还没被a给拷贝过来,否则,stx记录的是从x点开始拷贝k个的那个x值,等会后面要用到。sty则是随stx,stx要更新时,sty也要更新,sty初始为0,这时的sty为拷贝从b的y个位置开始的那个y值,总之,即输入x,y,k,stx记录x,sty记录y。最后查询pos节点,如果其stx或sty为0,说明这个节点还没有受到“侵染“,保持原来的b数组中的值,所以输出b[pos]。否则,已经收到”侵染“,输出a[pos-sty+stx],即从a中去与距离相等的元素,距离就是那个pos-sty,这时知道sty的作用了吧。。

代码:

/*3900KB 280ms*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define N 100010 int a[N],b[N];
int n,m; struct node
{
int stx,sty;
}tree[*N]; void build(int l,int r,int rt)
{
tree[rt].stx = tree[rt].sty = ;
if(l == r)
{
return;
}
int mid = (l+r)/;
build(l,mid,*rt);
build(mid+,r,*rt+);
} void pushdown(int rt)
{
if(tree[rt].stx)
{
tree[*rt].stx = tree[*rt+].stx = tree[rt].stx;
tree[*rt].sty = tree[*rt+].sty = tree[rt].sty;
tree[rt].stx = tree[rt].sty = ;
}
}
void change(int l,int r,int aa,int bb,int stx,int sty,int rt)
{
if(aa<=l&&bb>=r)
{
tree[rt].stx = stx;
tree[rt].sty = sty;
return;
}
pushdown(rt);
int mid = (l+r)/;
if(bb<=mid)
change(l,mid,aa,bb,stx,sty,*rt);
else if(aa>mid)
change(mid+,r,aa,bb,stx,sty,*rt+);
else
{
change(l,mid,aa,bb,stx,sty,*rt);
change(mid+,r,aa,bb,stx,sty,*rt+);
}
} node query(int l,int r,int pos,int rt)
{
if(l == r)
{
return tree[rt];
}
pushdown(rt);
int mid = (l+r)/;
if(pos<=mid)
return query(l,mid,pos,*rt);
return query(mid+,r,pos,*rt+);
} int main()
{ int i;
int x,y,k,pos;
int op;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(i=;i<=n;i++)
{
scanf("%d",&b[i]);
}
build(,n,);
for(i=;i<m;i++)
{
scanf("%d",&op);
if(op == )
{
scanf("%d%d%d",&x,&y,&k);
change(,n,y,y+k-,x,y,);
}
else
{
scanf("%d",&pos);
node ans = query(,n,pos,);
if(ans.stx == )
{
printf("%d\n",b[pos]);
}
else
{
printf("%d\n",a[pos-ans.sty+ans.stx]);
}
}
}
}
return ;
}

E.Circular RMQ ---Codeforces 52C

也是很简单的一道线段树,纯当练手了,还是那样维护,只不过可能换成两个区间查询和加值罢了。。还有值得一提的输入方式,因为比较坑爹的是输入不定,所以借鉴了别人的stringstream 方法,核心代码如下:

gets(buffer);
stringstream ss(buffer);
ss>>aa>>bb;

具体实现在下面。。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <utility>
#include <cstdlib>
#include <sstream>
using namespace std;
#define N 200010 struct node
{
lll mini;
lll addmark;
}tree[*N]; int n,m;
lll a[N]; void pushup(int rt)
{
tree[rt].mini = min(tree[*rt].mini,tree[*rt+].mini);
} void build(int l,int r,int rt)
{
tree[rt].addmark = ;
if(l == r)
{
tree[rt].mini = a[l];
return;
}
int mid = (l+r)/;
build(l,mid,*rt);
build(mid+,r,*rt+);
pushup(rt);
} void pushdown(int rt)
{
if(tree[rt].addmark)
{
tree[*rt].mini += tree[rt].addmark;
tree[*rt+].mini += tree[rt].addmark;
tree[*rt].addmark += tree[rt].addmark;
tree[*rt+].addmark += tree[rt].addmark;
tree[rt].addmark = ;
}
} void add(int l,int r,int aa,int bb,int val,int rt)
{
if(aa>r||bb<l)
return;
if(aa<=l&&bb>=r)
{
tree[rt].mini += val;
tree[rt].addmark += val;
return;
}
pushdown(rt);
int mid = (l+r)/;
if(aa<=mid)
add(l,mid,aa,bb,val,*rt);
if(bb>mid)
add(mid+,r,aa,bb,val,*rt+);
pushup(rt);
} lll query(int l,int r,int aa,int bb,int rt)
{
if(aa>r||bb<l)
return (lll)1e17;
if(aa<=l&&bb>=r)
{
return tree[rt].mini;
}
pushdown(rt);
int mid = (l+r)/;
if(bb<=mid)
return query(l,mid,aa,bb,*rt);
else if(aa>mid)
return query(mid+,r,aa,bb,*rt+);
else
{
return min(query(l,mid,aa,bb,*rt),query(mid+,r,aa,bb,*rt+));
}
} char buffer[]; int main()
{
int i,aa,bb;
lll val,ans;
while(scanf("%d",&n)!=EOF)
{
for(i=;i<=n;i++)
{
scanf("%I64d",&a[i]);
}
build(,n,);
scanf("%d",&m);
gets(buffer);
for(i=;i<m;i++)
{
gets(buffer);
stringstream ss(buffer);
ss>>aa>>bb;
aa++,bb++;
if(ss>>val)
{
if(aa<=bb)
{
add(,n,aa,bb,val,);
}
else
{
add(,n,aa,n,val,);
add(,n,,bb,val,);
}
}
else
{
if(aa<=bb)
ans = query(,n,aa,bb,);
else
{
lll res = query(,n,aa,n,);
ans = query(,n,,bb,);
ans = min(ans,res);
}
printf("%I64d\n",ans);
}
}
}
return ;
}

H.Vessels ---Codeforces 371D

这道题我原来出的时候记得是线段树,但是后来看别人的代码,没看见一个用线段树写的,,我去。原来硬搞也能过。。难点是想到,。下面放我借鉴别人的代码吧:

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define N 200010 int cap[N],jp[N],a[N]; int main()
{
int n,m;
int i,j;
int op,pos,val;
int st;
while(scanf("%d",&n)!=EOF)
{
memset(cap,,sizeof(cap));
for(i=;i<=n;i++)
{
scanf("%d",&a[i]);
jp[i] = i;
}
scanf("%d",&m);
for(i=;i<m;i++)
{
scanf("%d",&op);
if(op == )
{
scanf("%d%d",&pos,&val);
st = jp[pos];
while(cap[st]+val>=a[st]&&st<=n)
{
val -= (a[st]-cap[st]);
cap[st] = a[st];
st++;
}
if(st<=n)
cap[st] += val;
for(j=jp[pos];j<st;j++)
{
jp[j] = st;
}
jp[pos] = st;
}
else
{
scanf("%d",&pos);
printf("%d\n",cap[pos]);
}
}
}
return ;
}

Mango DS Traning #49 ---线段树3 解题手记的更多相关文章

  1. Mango DS Training #48 ---线段树2 解题手记

    Training address: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=38966#overview A.Count Color ...

  2. HDU 1754 线段树入门解题报告

    ---恢复内容开始--- 题意:给定区间,每个人的成绩, Q次询问,求每次询问区间中的最大值 思路:构造线段树 代码: #include<stdio.h> #include<algo ...

  3. POJ 3264 线段树入门解题报告

    题意:给n个值, Q次询问, 每次询问给定一个区间, 要求输出该区间最大最小值之差 思路:暴力的话每次询问都要遍历多次for循环一定会超时, 用线段树记录区间的信息(左边界右边界, 该区间最大值最小值 ...

  4. [NOIP2016 DAY1 T2]天天爱跑步-[差分+线段树合并][解题报告]

    [NOIP2016 DAY1 T2]天天爱跑步 题面: B[NOIP2016 DAY1]天天爱跑步 时间限制 : - MS 空间限制 : 565536 KB 评测说明 : 2s Description ...

  5. 洛谷 P3373 【模板】线段树 2 解题报告

    P3373 [模板]线段树 2 题目描述 如题,已知一个数列,你需要进行下面三种操作: 1.将某区间每一个数乘上\(x\) 2.将某区间每一个数加上\(x\) 3.求出某区间每一个数的和 输入输出格式 ...

  6. ACM Minimum Inversion Number 解题报告 -线段树

    C - Minimum Inversion Number Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d &a ...

  7. poj 2777 Count Color(线段树区区+染色问题)

    题目链接:  poj 2777 Count Color 题目大意:  给出一块长度为n的板,区间范围[1,n],和m种染料 k次操作,C  a  b  c 把区间[a,b]涂为c色,P  a  b 查 ...

  8. BZOJ2733 [HNOI2012]永无乡 【线段树合并】

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  9. 洛谷P4556 雨天的尾巴 线段树

    正解:线段树合并 解题报告: 传送门! 考虑对树上的每个节点开一棵权值线段树,动态开点,记录一个max(num,id)(这儿的id,define了一下,,,指的是从小到大排QAQ 然后修改操作可以考虑 ...

随机推荐

  1. ningx配置ModSecurity重启出现兼容性问题:ModSecurity: Loaded PCRE do not match with compiled!的解决方法

    nginx开启错误日志,然后重启nginx,出现如下信息: 2016/12/03 09:40:38 [notice] 18858#0: ModSecurity for nginx (STABLE)/2 ...

  2. 深入理解MySQL开发性能优化.pptx

    深入理解MySQL开发性能优化.pptx,依旧上传baidu pan http://pan.baidu.com/s/1jIwGslS,视频暂未出,培训完成后会更新.

  3. PHP调用SQL Server存储过程

    一.安装SQL Server Driver for PHP     在微软官网上发现了这个东西,他提供了一套PHP对MS2005/2008操作的全新函数库,并且支持UTF8,作为PHP的扩展运行.看来 ...

  4. 微信公共平台开发3 .net

    嗯,别的不说了现在开始接着上次http://www.cnblogs.com/QLJ1314/p/3838058.html  获取ACCESSTOKEN,开始吧,接下来我们就写发送文本消息吧. 首先建立 ...

  5. Echarts ecomfe 触摸屏 touch 在IE10下无法显示悬浮框

    问题描述: Windows 8 IE10浏览http://echarts.baidu.com/doc/example/line2.html 时,鼠标放置在数据点上时无法显示悬浮框. 正常情况为: 而现 ...

  6. 3.0之后在LinearLayout里增加分割线

    android:divider="@drawable/shape"<!--分割线图片--> android:showDividers="middle|begi ...

  7. 【原】开发路上疑难BUG调试记录

    之前遇到棘手的BUG总是在处理过后就不管了,导致后面碰到相同问题后重复工作太多.现专门开辟一篇日志以记录接下来一路上比较棘手的“坑”的修复历程: [C++篇] 1.mt.exe : general e ...

  8. 最新Burpsuite Pro v1.7.03 介绍和破解版下载

    0x00 介绍 Burp Suite 是用于攻击web 应用程序的集成平台.它包含了许多工具,并为这些工具设计了许多接口,以促进加快攻击应用程序的过程.所有的工具都共享一个能处理并显示HTTP 消息, ...

  9. css中font-family的中文字体

    说到css中的font-family,相信很多朋友经常用,但不知道当你遇到引用中文字体的时候你会怎么写?最近特别关注了下,发现最常用的基本有三种类型: 1.直接中文: 2.英文形式: 3.unicod ...

  10. Jmeter代理录制脚本

    录制的原理: 1.LR/Jmeter录制是针对网络通讯协议层面的,它只关心客户端与服务器端的通讯包2.LR/Jmeter的并发测试实际上就是并发客户端与服务器端的通讯过程3.压力是通过多进程/多线程方 ...