Copying Data
Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Description
We often have to copy large volumes of information. Such operation can take up many computer resources. Therefore, in this problem you are advised to come up with a way to copy some part of a number array into another one, quickly. More formally, you've got two arrays of integers a1, a2, ..., an and b1, b2, ..., bn of length n. Also, you've got m queries of two types: Copy the subsegment of array a of length k, starting from position x, into array b, starting from position y, that is, execute by + q = ax + q for all integer q( ≤ q < k). The given operation is correct — both subsegments do not touch unexistent elements.
Determine the value in position x of array b, that is, find value bx.
For each query of the second type print the result — the value of the corresponding element of array b. Input
The first line contains two space-separated integers n and m( ≤ n, m ≤ ) — the number of elements in the arrays and the number of queries, correspondingly. The second line contains an array of integers a1, a2, ..., an(|ai| ≤ ). The third line contains an array of integers b1, b2, ..., bn(|bi| ≤ ). Next m lines contain the descriptions of the queries. The i-th line first contains integer ti — the type of the i-th query ( ≤ ti ≤ ). If ti = , then the i-th query means the copying operation. If ti = , then the i-th query means taking the value in array b. If ti = , then the query type is followed by three integers xi, yi, ki( ≤ xi, yi, ki ≤ n) — the parameters of the copying query. If ti = , then the query type is followed by integer xi( ≤ xi ≤ n) — the position in array b. All numbers in the lines are separated with single spaces. It is guaranteed that all the queries are correct, that is, the copying borders fit into the borders of arrays a and b. Output
For each second type query print the result on a single line. Sample Input Input -
- Output - -1 这个题目很无语,读题读了块一个小时,发现不知道怎么去成段替换觉得用lazy不适合,后来日天大神跟我讲了一下用lazy的方法,秒懂。 但是写着写着发现有点乱了思路,又重新写了一遍写了1个小时,过了样例后WA了一次,不知道调哪里,然后自己跟着题目注释,突然发现lazy的变化规律越来越清晰。 果然思路混乱就去打注释才是最好的方法! 下面是写了我一个下午加晚上的题目的AC代码:

#include"iostream"
#include"algorithm"
#include"cstdio"
#include"cmath"
#include"cstring"
#define MX 110000
#define INF 0x3f3f3f3f
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
/* 题目没看懂百度了题意和思路:
给你两个数字序列a[]和lazy[],有两种操作,
一种是把起点为xi,长度为k的a[]的一段复制给以yi为起点,长度为k的lazy[]
还有一种操作是询问当前lazy[x]的数字是什么。 思路:
这道题可以用线段树成段更新做,属于染色一类线段树题目
可以这么想,对于任意一个数,记录它有没有被a[]的其中一段覆盖了
如果被覆盖了,可以记录它被覆盖的a[]的那段的起点st以及lazy[]被覆盖的起点ed
如果被覆盖,那么最后结果就是a[x1+ed-st]。 st表示这一线段是否被a[]数组覆盖,如果没有覆盖,那么st=0
如果覆盖,那么被a[]覆盖的区间范围是a[st]~a[st+k-1],ed同理,只不过记录的是lazy[]的开始位置。 对于操作1,输入x1,y1,k,只要使得区间[y1,y1+k-1]的st变成x1,ed变成y1.
对于操作2,输入x1,在线段树中寻找,如果这一点(即[x1,x1])的st是0,就输出c[x1],否则输出a[x1+ed-st]. */ int a[MX],b[MX];
int st1,st2;
int k;
struct tree {
int l,r,st,ed;
} lazy[MX<<2]; void Build(int l,int r,int rt) {
lazy[rt].l=l; //标记每个的位置
lazy[rt].r=r;
lazy[rt].st=lazy[rt].ed=0; //清空左右标记
if(l==r)return;
int m=(l+r)>>1;
Build(lson);
Build(rson);
} void PushDown(int rt){
if(lazy[rt].st!=-1) { //如果节点发生的变化
lazy[rt<<1].st=lazy[rt<<1|1].st=lazy[rt].st; //标记下移
lazy[rt<<1].ed=lazy[rt<<1|1].ed=lazy[rt].ed;
lazy[rt].st=lazy[rt].ed=-1;
}
} void UpData(int x1,int y1,int l,int r,int rt) {
if(lazy[rt].st==x1 && lazy[rt].ed==y1)return; //如果节点的变化重复,直接返回
if(lazy[rt].l==l && lazy[rt].r==r) { //如果查询到了目标的lazy点
lazy[rt].st=x1; //将lazy点的左右端点更新
lazy[rt].ed=y1;
return;
}
PushDown(rt);
int m=(lazy[rt].l+lazy[rt].r)>>1;
if(r<=m) UpData(x1,y1,l,r,rt<<1); //如果中点在右边,向左查询更新
else if(l>m) UpData(x1,y1,l,r,rt<<1|1); //如果中点在左边,向右查询更新
else {
UpData(x1,y1,lson); //如果中点在中间,向两边去更新
UpData(x1,y1,rson);
}
} void Query(int x,int rt) {
if(lazy[rt].st!=-1) {
st1=lazy[rt].st; //【一开始用的是 tree 类型函数返回 一个节点,蜜汁出错。最后还是换成全局整型来标记。】
st2=lazy[rt].ed;
return;
}
int m=(lazy[rt].l+lazy[rt].r)>>1;
if(x<=m) Query(x,rt<<1);
else Query(x,rt<<1|1);
} int main() {
int n,m,op,x,x1,y1;
while(~scanf("%d%d",&n,&m)) {
for(int i=1; i<=n; i++) {
scanf("%d",&a[i]);
}
for(int i=1; i<=n; i++) {
scanf("%d",&b[i]);
}
Build(1,n,1);
while(m--) {
scanf("%d",&op);
if(op==1) {
scanf("%d%d%d",&x1,&y1,&k);
UpData(x1,y1,y1,y1+k-1,1);
} else if(op==2) {
scanf("%d",&x);
st1=st2=0;
Query(x,1);
if(st1==0) {
printf("%d\n",b[x]);//如果这点没有标记,则说明没有移动过这点,输出b[aa];
} else {
printf("%d\n",a[x-st2+st1]);//否则这点就移动过输出移动区间后的值也就是a[aa-Q.ed+Q.st];
}
}
}
}
return 0;
}
  

  

ACM: Copying Data 线段树-成段更新-解题报告的更多相关文章

  1. hdu 4747【线段树-成段更新】.cpp

    题意: 给出一个有n个数的数列,并定义mex(l, r)表示数列中第l个元素到第r个元素中第一个没有出现的最小非负整数. 求出这个数列中所有mex的值. 思路: 可以看出对于一个数列,mex(r, r ...

  2. Codeforces Round #149 (Div. 2) E. XOR on Segment (线段树成段更新+二进制)

    题目链接:http://codeforces.com/problemset/problem/242/E 给你n个数,m个操作,操作1是查询l到r之间的和,操作2是将l到r之间的每个数xor与x. 这题 ...

  3. POJ 2777 Count Color (线段树成段更新+二进制思维)

    题目链接:http://poj.org/problem?id=2777 题意是有L个单位长的画板,T种颜色,O个操作.画板初始化为颜色1.操作C讲l到r单位之间的颜色变为c,操作P查询l到r单位之间的 ...

  4. HDU1698_Just a Hook(线段树/成段更新)

    解题报告 题意: 原本区间1到n都是1,区间成段改变成一个值,求最后区间1到n的和. 思路: 线段树成段更新,区间去和. #include <iostream> #include < ...

  5. HDU 3577 Fast Arrangement ( 线段树 成段更新 区间最值 区间最大覆盖次数 )

    线段树成段更新+区间最值. 注意某人的乘车区间是[a, b-1],因为他在b站就下车了. #include <cstdio> #include <cstring> #inclu ...

  6. poj 3468 A Simple Problem with Integers 【线段树-成段更新】

    题目:id=3468" target="_blank">poj 3468 A Simple Problem with Integers 题意:给出n个数.两种操作 ...

  7. POJ3468_A Simple Problem with Integers(线段树/成段更新)

    解题报告 题意: 略 思路: 线段树成段更新,区间求和. #include <iostream> #include <cstring> #include <cstdio& ...

  8. poj 3648 线段树成段更新

    线段树成段更新需要用到延迟标记(或者说懒惰标记),简单来说就是每次更新的时候不要更新到底,用延迟标记使得更新延迟到下次需要更新or询问到的时候.延迟标记的意思是:这个区间的左右儿子都需要被更新,但是当 ...

  9. 线段树(成段更新) POJ 3468 A Simple Problem with Integers

    题目传送门 /* 线段树-成段更新:裸题,成段增减,区间求和 注意:开long long:) */ #include <cstdio> #include <iostream> ...

随机推荐

  1. 如何使用Case进行简单判断

    Case具有两种格式.简单Case函数和Case搜索函数. --简单Case函数 CASE sex ' THEN '男' ' THEN '女' ELSE '其他' END --Case搜索函数 ' T ...

  2. async/await 异步编程(转载)

    转载地址:http://www.cnblogs.com/teroy/p/4015461.html 前言 最近在学习Web Api框架的时候接触到了async/await,这个特性是.NET 4.5引入 ...

  3. 闲谈SQL脚本优化

    摘要: 闲来无事,便想寻找大师级别优化SQL脚本案例,也算是读后留点笔记,摘录内容都会链接到所参考网址,如有冒犯,还望博主见谅:有些文章只有多动手多动脑才能理解其中的意思,看了需要实际操作,才不枉大师 ...

  4. poj 1182:食物链(种类并查集,食物链问题)

    食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 44168   Accepted: 12878 Description ...

  5. hibernate中many-to-one关联时出现ObjectNotFoundException异常

    采用多对一关联,如果一的那端删除了,多的这端无法感知,虽然数据库中可以通过外键配置将多的一端置空,可是在hibernate里面我暂时不知道如何处理. 目前采用的方式: 1.首先,数据库中需要配置好外键 ...

  6. TCP 连接中断的判断

    关于TCP 3次握手,4次分手就不多说了.如何判断TCP连接是否中断是个大问题. 1 TCPKeep-alive 机制 并不是TCP 规范的一部分,实现细节差距大. 2 使用heartbeat 检测 ...

  7. phpMailer邮件发送

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. 设置SecureCRT会话的缓冲区大小

    转自:http://blog.csdn.net/imxiangzi/article/details/7457703 在使用SecureCRT操作设备时,默认的回滚行数为500行.可以通过打开[选项]- ...

  9. Poisson Image Editing

    说起泊松,可以顺便提及一下泊松同学的老师,拉普拉斯.学图像或是信号的,一定对拉普拉斯算子和拉普拉斯卷积很熟悉.在泊松图像融合出现之前,也有一种叫Laplacian pyramid blending的融 ...

  10. barabasilab-networkScience学习笔记4-无标度特征

    第一次接触复杂性科学是在一本叫think complexity的书上,Allen博士很好的讲述了数据结构与复杂性科学,barabasi是一个知名的复杂性网络科学家,barabasilab则是他所主导的 ...