您的位置:首页 > 产品设计 > UI/UE

【清华集训2017模拟】Sequence

2017-09-04 20:32 477 查看

Description



Input



Output

共m行,每行一个整数表示询问的答案

Sample Input

10

5 4 8 9 1 6 3 2 7 10

5 6 3 4 1 2 10 7 8 9

5

3 7 2 4 1

3 10 3 7 4

6 8 1 3 1

9 10 2 2 1

2 3 2 2 1

Sample Output

2

8

2

9

3

Solution

这题一看到题就有一种很显然的做法,简单来说就是分块套分块套分块,然而编程复杂度太高

稍微分析一下就会发现,如果以原顺序为一维,第一关键字为二维,第二关键字为权值,那么那些点都可以抽象成一个二维平面内的点,询问就是询问一个矩形内权值第几的点的权值

那么显然可以用树套树来做,然而我不会

所以可以用一种更简单的方法:整体二分

这是我第一次打整体二分,所以可能有点难看

思想就是,每次二分出的mid,然后对每个询问判断这个询问的答案比mid大还是比mid小,分为两部分并继续二分

那么在这题中,如果将询问和点都按照第一维来排序,依次操作,如果是点就加入数据结构中,查询就用关键字直接查询。

那么数据结构中有的就是第一维被压扁,只有第二维的值了

在查询矩形时,就可以变为查询区间,矩形的左右两个相减,就可以只需要一个一维的数据结构,查询点数,用树状数组就可以维护了

可能说不清楚,自行看看标吧

Code

#include<cstdio>
#include<algorithm>
#include<cstring>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define N 3010000
#define lowbit(x) ((x)&(-x))
using namespace std;
struct node{
int x,y,z,i,q,w,k;
}a
,c
,d
;
struct note{
int l,r,d;
}t
;
int n,m,tot,b
,ans
,ta
;
bool cnt(node x,node y){return x.z<y.z||(x.z==y.z&&x.q<y.q);}
void ins(int v,int i,int j,int x)
{
t[v].d++;if(i==j) return;
int m=(i+j)/2;
if(x<=m) t[++tot]=t[t[v].l],t[v].l=tot,ins(t[v].l,i,m,x);
else t[++tot]=t[t[v].r],t[v].r=tot,ins(t[v].r,m+1,j,x);
}
int get(int v1,int v2,int i,int j,int x)
{
if(i==j) return i;
int m=(i+j)/2;
if(t[t[v2].l].d-t[t[v1].l].d>=x) return get(t[v1].l,t[v2].l,i,m,x);
else return get(t[v1].r,t[v2].r,m+1,j,x-t[t[v2].l].d+t[t[v1].l].d);
}
void add(int x,int y)
{
for(;x<=n;x+=lowbit(x)) ta[x]+=y;
}
int que(int x)
{
int ans=0;
for(;x;x-=lowbit(x)) ans+=ta[x];
return ans;
}
void dg(int q,int w,int l,int r)
{
if(l==r)
{
fo(i,q,w) if(a[i].q) ans[a[i].i]=l;
return;
}
int mid=(l+r)/2;
int t1=0,t2=0;
fo(i,q,w)
if(a[i].q) b[a[i].i]+=(que(a[i].y)-que(a[i].x-1))*a[i].w;
else if(a[i].x<=mid) add(a[i].y,1);
fo(i,q,w)
if(a[i].q)
{
if(b[a[i].i]>=a[i].k) c[++t1]=a[i];
else d[++t2]=a[i],d[t2].k-=b[a[i].i];
}
else
{
if(a[i].x<=mid) c[++t1]=a[i];
else d[++t2]=a[i];
}
fo(i,q,w)
if(a[i].q) b[a[i].i]=0;
else if(a[i].x<=mid) add(a[i].y,-1);
fo(i,1,t1) a[q+i-1]=c[i];
fo(i,1,t2) a[q+t1+i-1]=d[i];
dg(q,q+t1-1,l,mid);
dg(q+t1,w,mid+1,r);
}
int main()
{
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
scanf("%d",&n);tot=n;
fo(i,1,n) scanf("%d",&a[i].y),a[i].z=i,a[i].q=0,t[i]=t[i-1],ins(i,1,n,a[i].y);
fo(i,1,n) scanf("%d",&a[i].x);
tot=n;
scanf("%d",&m);
fo(i,1,m)
{
int l,r,x,y,k;scanf("%d%d%d%d%d",&l,&r,&x,&y,&k);
x=get(l-1,r,1,n,x);y=get(l-1,r,1,n,y);
a[++tot].q=1;a[tot].z=l-1;a[tot].x=x;a[tot].y=y;a[tot].i=i;a[tot].w=-1;a[tot].k=k;
a[++tot].q=1;a[tot].z=r;a[tot].x=x;a[tot].y=y;a[tot].i=i;a[tot].w=1;a[tot].k=k;
}
sort(a+1,a+tot+1,cnt);
dg(1,tot,1,n);
fo(i,1,m) printf("%d\n",ans[i]);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: