【PA2011】Kangaroos
来源:互联网 发布:word转繁体 mac 编辑:程序博客网 时间:2024/05/14 16:04
Description
定义两个区间互相匹配表示这两个区间有交集。
给出长度为N的区间序列A,M次询问,每次询问序列A中最长的连续子序列,使得子序列中的每个区间都与[L,R]互相匹配
N<=50000,M<=200000
Input
Output
Sample Input
3 3
2 5
1 3
6 6
3 5
1 10
7 9
Sample Output
2
3
0
HINT
Source
从Claris permu那题的题解可以拿来给这个题用,发现完全一样
考虑把一个区间[L,R]当成(L,R)
然后把询问点插入进kdtree,可以发现kdtree的一个点,对他有贡献的区域是他右下方的矩形
然后把n个序列点按顺序逐个插入进去,可以发现他贡献出答案的点是这n个点左上方的.对左上方的贡献是+1,其他点则是清零
可以对m个询问点维护以下信息:历史点最大序列长,历史矩阵最大序列长,历史点最大清零时间,历史矩阵最大清零时间,最小清零时间
显然可以用当前时间和之前的清零时间算一算算出一个序列长度
就这样标记打一打就行了
但是标记打起来非常麻烦..参考了鸟神的题解..
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define MAXN 200010#define Dnum 2#define GET (ch>='0'&&ch<='9')using namespace std;inline void in(int &x){ char ch=getchar();x=0; while (!GET) ch=getchar(); while (GET) x=x*10+ch-'0',ch=getchar();}int n,m,root;bool cmp_d;int id[MAXN],x[MAXN],y[MAXN];struct KDtree{ int ch[2],f,d[Dnum],minn[Dnum],maxn[Dnum],maxv[Dnum],maxt[Dnum],mint; inline void init() { for (int i=0;i<Dnum;++i) minn[i]=maxn[i]=d[i],maxv[i]=maxt[i]=0; } inline bool operator < (const KDtree& a)const { return d[cmp_d]<a.d[cmp_d]; }}tree[MAXN];inline void add(int rt,int x,int y){ if (~x) { if (~tree[rt].mint) tree[rt].maxv[0]=max(tree[rt].maxv[0],x-tree[rt].maxt[0]-1); else tree[rt].mint=x; tree[rt].maxv[1]=max(tree[rt].maxv[1],x-tree[rt].maxt[1]-1); tree[rt].maxt[0]=tree[rt].maxt[1]=y; }}inline void push_up(int rt){ for (int x=0,i=0;i<2;++i) if ((x=tree[rt].ch[i])) for (int j=0;j<Dnum;++j) tree[rt].minn[j]=min(tree[rt].minn[j],tree[x].minn[j]), tree[rt].maxn[j]=max(tree[rt].maxn[j],tree[x].maxn[j]);}inline void push_down(int rt){ int x=tree[rt].mint,y=tree[rt].maxt[0]; for (int i=0,j=0;i<2;++i) if ((j=tree[rt].ch[i])) add(j,x,y); tree[rt].mint=-1;}int rebuild(int l=1,int r=m,bool d=0,int f=0){ cmp_d=d;int mid=(l+r)>>1;nth_element(tree+l,tree+mid,tree+r+1); id[tree[mid].f]=mid;tree[mid].f=f;tree[mid].init(); if (l!=mid) tree[mid].ch[0]=rebuild(l,mid-1,d^1,mid); if (r!=mid) tree[mid].ch[1]=rebuild(mid+1,r,d^1,mid); return push_up(mid),mid;}inline int check(int x1,int y1,int x2,int y2,int x,int y){ int ret=0; ret+=(x1<=x&&y1>=y);ret+=(x1<=x&&y2>=y);ret+=(x2<=x&&y1>=y);ret+=(x2<=x&&y2>=y); return ret?(ret==4?1:2):0;}void modify(int rt,int x,int y,int id){ int flag=check(tree[rt].minn[0],tree[rt].minn[1],tree[rt].maxn[0],tree[rt].maxn[1],x,y); if (!flag) { add(rt,id,id);return; } if (flag==1) return; if (tree[rt].d[0]>x||tree[rt].d[1]<y) tree[rt].maxv[1]=max(tree[rt].maxv[1],id-tree[rt].maxt[1]-1),tree[rt].maxt[1]=id; push_down(rt); for (int i=0;i<2;++i) if (tree[rt].ch[i]) modify(tree[rt].ch[i],x,y,id);}void update(int rt,int x){ push_down(rt); tree[rt].maxv[1]=max(tree[rt].maxv[1],n-tree[rt].maxt[1]); tree[rt].maxv[1]=max(tree[rt].maxv[1],x); tree[rt].maxv[0]=max(tree[rt].maxv[0],x); tree[rt].maxv[1]=max(tree[rt].maxv[1],tree[rt].maxv[0]); for (int i=0;i<2;++i) if (tree[rt].ch[i]) update(tree[rt].ch[i],tree[rt].maxv[0]);}int main(){ in(n);in(m); for (int i=1;i<=n;++i) in(y[i]),in(x[i]); for (int i=1;i<=m;++i) in(tree[i].d[0]),in(tree[i].d[1]),tree[i].f=i; root=rebuild(); for (int i=1;i<=n;++i) modify(root,x[i],y[i],i); update(root,0); for (int i=1;i<=m;++i) printf("%d\n",tree[id[i]].maxv[1]);}
1 0
- 【PA2011】Kangaroos
- 【BZOJ】4130: [PA2011]Kangaroos【KD树——最长连续1的子段长度】
- 【PA2011】【BZOJ3073】Journeys
- bzoj 3073: [Pa2011]Journeys
- pa2011 切题记
- Counting Kangaroos is Fun
- A. Counting Kangaroos is Fun
- 【PA2011】【BZOJ3069】Hard Choice 艰难的选择
- BZOJ3069: [Pa2011]Hard Choice 艰难的选择
- 3073: [Pa2011]Journeys|线段树|BFS
- BZOJ3069 [Pa2011]Hard Choice 艰难的选择
- CodeForces 372 A. Counting Kangaroos is Fun
- cf 372A Counting Kangaroos is Fun
- codeforces327A Counting Kangaroos is Fun【二分】
- 【CodeForces】[372A]Counting Kangaroos is Fun
- CodeForces 372 A Counting Kangaroos is Fun
- CodeForces 372A Counting Kangaroos is Fun
- Codeforces-Counting Kangaroos is Fun【贪心】【二分】
- 程序员如何艺术的提升技术、影响力&赚钱
- C++作业4
- 主线程捕捉线程池中线程抛出的异常
- Android性能优化
- 只要10000小时 你就是出类拔萃的人
- 【PA2011】Kangaroos
- JAVA-Java基础语法
- 通知的使用和通知对键盘的监听
- HDU-5760 Machine (水 十进制化成三进制) From BestCoder #81(dir2)
- 【BZOJ4358】permu
- 针对字符和字符串是否可以修改. 详解,附代码
- IBM Rational Rose2007 安装及故障处理
- 【BZOJ3489】A simple rmq problem
- FZUOJ-2222-ABCDEFG From 校赛 A