操作无论是U还是L,都会使原图形分裂成两个图形,且两个图形的操作互不影响

我们又发现由于操作点只可能在下斜线上,如果将操作按x排序

那么无论是U还是L,都会将操作序列完整分割成两半,且两个操作序列互不影响

这样我们就可以对操作进行分治,每次找到最靠前的操作,并将操作序列分割

对于U操作而言,计算其答案只需要知道当前列最靠下的那一行

对于L操作而言,计算其答案只需要知道当前行最靠右的那一列

分治的时候动态维护即可

注:这样的话最坏情况会递归20w层,在CF上会爆栈,所以我的代码人为的开了栈空间

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<map>
#include<iostream>
using namespace std;

const int maxn=200010;
int n,m;
struct OP{
	int a,b,id;
	char c;
}A[maxn];
int mn[maxn<<2];
int ans[maxn];
map<int,bool>vis;

bool cmp(const OP &A,const OP &B){return A.a<B.a;}
void ch_read(char &ch){
	ch=getchar();
	while(ch<'!')ch=getchar();
}
int Min(int a,int b){return A[a].id<A[b].id?a:b;}
void build(int o,int L,int R){
	if(L==R){mn[o]=L;return;}
	int mid=(L+R)>>1;
	//cout<<mid<<endl;
	build(o<<1,L,mid);
	build(o<<1|1,mid+1,R);
	mn[o]=Min(mn[o<<1],mn[o<<1|1]);
}
int ask(int o,int L,int R,int x,int y){
	if(L>=x&&R<=y)return mn[o];
	int mid=(L+R)>>1;
	if(y<=mid)return ask(o<<1,L,mid,x,y);
	else if(x>mid)return ask(o<<1|1,mid+1,R,x,y);
	else return Min(ask(o<<1,L,mid,x,y),ask(o<<1|1,mid+1,R,x,y));
}
void Solve(int L,int R,int Low,int Right){
	if(L>R)return;
	int now=ask(1,1,m,L,R);
	if(vis[A[now].a]){
		Solve(L,now-1,Low,Right);
		Solve(now+1,R,Low,Right);
		return;
	}
	vis[A[now].a]=true;
	if(A[now].c=='U'){
		ans[A[now].id]=A[now].b-Low;
		Solve(L,now-1,Low,Right);
		Solve(now+1,R,Low,A[now].a);
	}else{
		ans[A[now].id]=A[now].a-Right;
		Solve(L,now-1,A[now].b,Right);
		Solve(now+1,R,Low,Right);
	}return;
}

int main(){
	int __size__ = 20 << 20; // 20MB
	char *__p__ = (char*)malloc(__size__) + __size__;
	__asm__("movl %0, %%esp\n" :: "r"(__p__));
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;++i){
		scanf("%d%d",&A[i].a,&A[i].b);
		ch_read(A[i].c);A[i].id=i;
	}
	sort(A+1,A+m+1,cmp);
	build(1,1,m);
	Solve(1,m,0,0);
	for(int i=1;i<=m;++i)printf("%d\n",ans[i]);
	return 0;
}

  

另外附上官方题解:

还是上面的思路,我们很容易发现:

对于每一行,只需要知道其最靠右覆盖的列

对于每一列,只需要知道其最靠下覆盖的行

我们可以建两棵线段树,分别维护行的信息和列的信息

每次操作分别更改两棵线段树即可

又因为n很大,所以我们需要对行和列离散化

随机推荐

  1. 交换机做Channel-Group

    core1#conf tEnter configuration commands, one per line.  End with CNTL/Z.core1(config)#inter range g ...

  2. 1029. Median (25)

    分析: 考察归并排序,用简单的快排会超时. #include <iostream> #include <stdio.h> #include <algorithm> ...

  3. 老项目的#iPhone6与iPhone6Plus适配#iOS8无法开启定位问题和#解决方案#

    本文永久地址为 http://www.cnblogs.com/ChenYilong/p/4020359.html,转载请注明出处. iOS8的定位和推送的访问都发生了变化, 下面是iOS7和iOS8申 ...

  4. 文件批量上传的工具,要实现暂停继续、断点续传等功能(使用QtNetwork和QHttpMultiPart,和定时器检查超时)

    最近在做一个文件批量上传的工具,要实现暂停继续.断点续传等功能.利用Qt自带的QtNetwork模块,完成这些需求并没有费多少周章,主要思路就是将文件分块,然后用while循环依次传输.具体实现代码比 ...

  5. JS与OC交互--简单使用

    直接上代码 .m文件 #import "ViewController.h" @interface ViewController () <UIWebViewDelegate&g ...

  6. 【转载】JavaScript继承详解(二)

    这一章我们将会重点介绍JavaScript中几个重要的属性(this.constructor.prototype), 这些属性对于我们理解如何实现JavaScript中的类和继承起着至关重要的作用. ...

  7. Mycat 读写分离详解

    Mycat 的读写分离是依赖数据库级别的数据主从同步的基础上来实现的(Mysql 的主从配置链接),Mycat 的读写分离是在 schema.xml 配置的 dataHost 节点的 balance ...

  8. Servlet再度学习

    虽然Servlet已经使用很多了,但是一直都仅局限在其使用操作上. 最近有空想对它进行一个相对全面的了解. 下面是博主整理的一篇博文. 一.Servlet简介 Servlet(Server Apple ...

  9. Python3 字典 items() 方法

    描述 Python 字典 items() 方法以列表返回可遍历的(键, 值) 元组数组. 语法 items()方法语法: dict.items() 参数 NA. 返回值 返回可遍历的(键, 值) 元组 ...

  10. Play XML Entities

    链接:https://pentesterlab.com/exercises/play_xxe/course Introduction This course details the exploitat ...