CodeForces 292E Copying Data

版权声明:本文为博主原创文章,转载请联系博主(通常都会同意就是了) https://blog.csdn.net/cccccwb/article/details/86593742

题解:裸上一棵线段树就可以解决了。

用线段树维护一个一开始全为0的数列,每次修改操作先记录下来,把这次修改操作所影响到位置对应的区间修改为这次操作的序数(也就是第几次操作)。查询的时候,先查询这个区间里面的对应位置,看看最后影响到这个数字的操作是哪一个,找到那次操作的具体内容,对比一下就可以得到答案了。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#define lson (nd<<1)
#define rson (nd<<1|1)
using namespace std;

struct node{
	int num;
	bool flag;
}t[1000010];

void pd(int nd)
{if(!t[nd].flag) return ;t[lson].num=t[rson].num=t[nd].num;t[lson].flag=t[rson].flag=1;t[nd].flag=0;}

void build(int L,int R,int nd)
{
    t[nd].num=-1;
	if(L==R) return ;
	int mid=(L+R)>>1;
	build(L,mid,lson);build(mid+1,R,rson);
}

int find(int L,int R,int nd,int x)
{
	pd(nd);
	if(L==R) return t[nd].num;
	int mid=(L+R)>>1;
	if(x<=mid) return find(L,mid,lson,x);
	return find(mid+1,R,rson,x);
}

void modify(int L,int R,int l,int r,int nd,int v)
{
	pd(nd);
	if(l<=L&&R<=r){t[nd].num=v;t[nd].flag=1;return ;}
	int mid=(L+R)>>1;
	if(l<=mid) modify(L,mid,l,r,lson,v);
	if(r>mid) modify(mid+1,R,l,r,rson,v);
}

int n,m,cnt;
int a[200010],b[200010],q[200010][3];

int main()
{
	int x,y;
	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]);
	for(int i=1;i<=m;i++)
	{
	   scanf("%d",&x);
	   if(x==1)
	   {
	   	 cnt++;
	   	 scanf("%d%d%d",&q[cnt][0],&q[cnt][2],&q[cnt][1]);
	   	 modify(1,n,q[cnt][2],q[cnt][2]+q[cnt][1]-1,1,cnt);
	   }
	   else
	   {
	   	 scanf("%d",&y);
	   	 x=find(1,n,1,y);
	   	 if(x<=0) printf("%d\n",b[y]);
	   	 else printf("%d\n",a[q[x][0]+y-q[x][2]]);
	   }
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/cccccwb/article/details/86593742