CodeForces 173E

来源:互联网 发布:兼职淘宝新媒体编辑 编辑:程序博客网 时间:2024/05/02 04:54

线段树
按能力值从小到大排序,
预处理以第i个人为组长的最大组
然后按能力值反向做更新线段树

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<vector>using namespace std;#define pb push_back#define ll o<<1#define rr o<<1|1#define mid (l+r)/2const int N=1e5+100;struct Node {    int r,a,id;    bool operator<(const Node & th)const{        return r<th.r;    }}node[N];int aa[N],top;int cc[N];int qu(int x){    int ans=0;    while(x){        ans+=cc[x];x-=x&-x;    }    return ans;}void up(int x){    while(x<=top){        cc[x]+=1;x+=x&-x;    }}int L,R;int mx[N<<2];void update(int l,int r,int o,int x,int v){    if(l==r){        mx[o]=max(mx[o],v);return ;    }    if(x<=mid)update(l,mid,ll,x,v);    else update(mid+1,r,rr,x,v);    mx[o]=max(mx[ll],mx[rr]);}int query(int l,int r,int o){    if(L<=l&&r<=R){        return mx[o];    }    int ans=-1;    if(L<=mid)ans=max(ans,query(l,mid,ll));    if(R>mid)ans=max(ans,query(mid+1,r,rr));    return ans;}int num[N];int ag[N],ra[N];int ask[N][2];int ans[N];int n,k;int fun(int x){    //printf("%d %dask\n",ask[x][0],ask[x][1]);    int l=ag[ask[x][0]],r=ag[ask[x][1]];    if(l>r)swap(l,r);    int ans=-1;    L=lower_bound(aa,aa+top,r-k)-aa+1;R=lower_bound(aa,aa+top,l+k)-aa+1;    if(R>top||aa[R-1]>l+k)R--;    if(L<=R)ans=query(1,top,1);    return ans;}vector<int> vv[N];int main(){    #ifdef DouBi    freopen("in.cpp","r",stdin);    #endif // DouBi    while(scanf("%d%d",&n,&k)!=EOF){        for(int i=0;i<n;i++)scanf("%d",&node[i].r),node[i].id=i,ra[i]=node[i].r;        for(int i=0;i<n;i++)scanf("%d",&node[i].a),aa[i]=node[i].a,ag[i]=aa[i];        sort(aa,aa+n);top=unique(aa,aa+n)-aa;        for(int i=0;i<n;i++){            node[i].a=lower_bound(aa,aa+top,node[i].a)-aa+1;        }        sort(node,node+n);//        for(int i=0;i<n;i++){//            printf("%d %d\n",node[i].a,node[i].r);//        }printf("node\n");        memset(cc,0,sizeof(cc));        for(int i=0;i<n;i++){            int j=i;up(node[j].a);            while(j+1<n&&node[j+1].r==node[i].r){                j++;up(node[j].a);            }            for(int k1=i;k1<=j;k1++){                int r=lower_bound(aa,aa+top,aa[node[i].a-1]+k)-aa+1;                if(r>top||aa[r-1]>aa[node[i].a-1]+k)r--;                int l=lower_bound(aa,aa+top,aa[node[i].a-1]-k)-aa+1;                num[k1]=qu(r)-qu(l-1);            }            i=j;        }//        for(int i=0;i<n;i++)printf("%d ",num[i]);printf("num\n");        for(int i=0;i<n;i++)vv[i].clear();        int q;scanf("%d",&q);        for(int i=0;i<q;i++){            int x,y;scanf("%d%d",&x,&y);x--;y--;            ask[i][0]=x;ask[i][1]=y;            if(ra[x]>=ra[y])vv[x].pb(i);            if(ra[y]>=ra[x])vv[y].pb(i);        }        memset(mx,-1,sizeof(mx));        memset(ans,-1,sizeof(ans));        for(int i=n-1;i>=0;i--){            int j=i;update(1,top,1,node[j].a,num[j]);            while(j-1>=0&&node[j-1].r==node[i].r){                j--;update(1,top,1,node[j].a,num[j]);            }            for(int k2=j;k2<=i;k2++){                int id=node[k2].id;                for(int k1=0;k1<vv[id].size();k1++){                    ans[vv[id][k1]]=max(ans[vv[id][k1]],fun(vv[id][k1]));                }            }            i=j;        }        for(int i=0;i<q;i++){            printf("%d\n",ans[i]);        }    }    return 0;}
0 0
原创粉丝点击