【JZOJ 5296】【清华集训2017模拟】Sequence

来源:互联网 发布:高斯步枪 知乎 编辑:程序博客网 时间:2024/05/19 17:56

这里写图片描述

Solution

发现,那个条件2其实没有用,可以用主席树预处理一下,转为数值在x,y之间,
那么这题就变成了求二维平面上的第k大,
这个用整体二分即可,

复杂度:O(nlog(n)2)

Code

#include <cstdio>#include <cstdlib>#include <algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fod(i,a,b) for(int i=a;i>=b;i--)#define min(q,w) ((q)>(w)?(w):(q))#define max(q,w) ((q)<(w)?(w):(q))#define NX(q) ((q)&(-(q)))#define Gsum(l,r) (find(r)-find((l)-1))using namespace std;const int N=100500;int read(int &n){    char ch=' ';int q=0,w=1;    for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());    if(ch=='-')w=-1,ch=getchar();    for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;}int m,n,ans;struct qqww{    int x,y,v;}a[N],p1[N];struct qwqw{    int x,y,v,i,k,p;}b[N*2],pb[N*2];int root[N],b10;struct qwqwq{    int l,r,v;}b1[N*70];int f[N];int c[N],Ans[N];bool PX(qwqw q,qwqw w){return q.p<w.p;}void build(int l,int r,int e1,int &e,int l1){    if(!e||e1==e)b1[e=++b10]=b1[e1];    if(l==r){b1[e].v++;return;}    b1[e].v++;    int t=(l+r)>>1;    if(l1<=t)build(l,t,b1[e1].l,b1[e].l,l1);    else build(t+1,r,b1[e1].r,b1[e].r,l1);}int findr(int l,int r,int e1,int e,int l1){    if(l==r)return l;    int t=(l+r)>>1;    if(!b1[e].r||b1[b1[e].l].v-b1[b1[e1].l].v>=l1)return findr(l,t,b1[e1].l,b1[e].l,l1);    return findr(t+1,r,b1[e1].r,b1[e].r,l1-b1[b1[e].l].v+b1[b1[e1].l].v);}void add(int q,int e){for(int i=q;i<=n;i+=NX(i))f[i]+=e;}int find(int q){    int ans=0;    for(int i=q;i;i-=NX(i))ans+=f[i];    return ans;}void divide(int l,int r,int L,int R,int L1,int R1){    if(l==r)    {        fo(i,L1,R1)Ans[b[i].i]=l;        return;    }    if(L1>R1||L>R)return;    int t=(l+r)>>1;    int T=0;    fo(i,L,R)    {        a[i-T]=a[i];        if(a[i].v>t)p1[++T]=a[i];    }    T=R-T;    fo(i,T+1,R)a[i]=p1[i-T];    int q=L1;    fo(i,L,T)    {        for(;b[q].p<a[i].x&&q<=R1;q++)        {            c[b[q].i]+=b[q].k*Gsum(b[q].x,b[q].y);        }        add(a[i].y,1);    }    for(;q<=R1;q++)c[b[q].i]+=b[q].k*Gsum(b[q].x,b[q].y);    q=0;    fo(i,L1,R1)    {        b[i-q]=b[i];        if(c[b[i].i]<b[i].v)        {            b[i].v-=c[b[i].i];            q++;            pb[q]=b[i];        }        if(b[i].k>0)c[b[i].i]=0;    }    fo(i,R1-q+1,R1)b[i]=pb[i-R1+q];    fo(i,L,T)add(a[i].y,-1);    divide(l,t,L,T,L1,R1-q);    divide(t+1,r,T+1,R,R1-q+1,R1);}int main(){    freopen("sequence.in","r",stdin);    freopen("sequence.out","w",stdout);    int q,w,e,_,l,r,x,y;    read(n);    fo(i,1,n)read(a[i].y),a[i].x=i;    fo(i,1,n)    {        read(a[i].v);        build(1,n,root[i-1],root[i],a[i].y);    }    read(m);    fo(i,1,m)    {        read(b[i*2-1].p),read(b[i*2].p);        b[i*2-1].p--;        read(q),read(w);        b[i*2].x=b[i*2-1].x=findr(1,n,root[b[i*2-1].p],root[b[i*2].p],q);        b[i*2].y=b[i*2-1].y=findr(1,n,root[b[i*2-1].p],root[b[i*2].p],w);        b[i*2].v=read(b[i*2-1].v);        b[i*2-1].k=-1;b[i*2].k=1;        b[i*2-1].i=b[2*i].i=i;    }    sort(b+1,b+1+2*m,PX);    divide(1,n,1,n,1,m*2);    fo(i,1,m)printf("%d\n",Ans[i]);    return 0;}
阅读全文
0 0
原创粉丝点击