bzoj 4991 [Usaco2017 Feb]Why Did the Cow Cross the Road III 树状数组套Treap

来源:互联网 发布:app store推荐软件 编辑:程序博客网 时间:2024/06/06 01:10

Description

Farmer John is continuing to ponder the issue of cows crossing the road through his farm, introduced
in the preceding two problems. He realizes now that the threshold for friendliness is a bit more su
btle than he previously considered – breeds aa and bb are now friendly if |a-b|≤K, and unfriendly
otherwise.Given the orderings of fields on either side of the road through FJ’s farm, please count t
he number of unfriendly crossing pairs of breeds, where a crossing pair of breeds is defined as in t
he preceding problems.
Input

The first line of input contains N (1≤N≤100,000) and K (0≤K < N).
The next N lines describe the order, by breed ID, of fields on one side of the road;
each breed ID is an integer in the range 1…N. The last N lines describe the order, by breed ID,
of the fields on the other side of the road. Each breed ID appears exactly once in each ordering.
Output

Please output the number of unfriendly crossing pairs of breeds.
Sample Input

4 1

4

3

2

1

1

4

2

3
Sample Output

2

In this example, breeds 1 and 4 are unfriendly and crossing, as are breeds 1 and 3.
HINT


传送门
题解传送门
就是个三维偏序。
本来以为treap可以快到飞起……结果T到怀疑人生= =
最终还是打了4个表AC的……
luogu大牛分站开了O2结果94……最大的点最好的时候是1.5s。。
bzoj评测机就更加慢啦。。实测9s结果光荣TLE……
(怀疑人生.jpg)
时限有点恶心啦。。cdq实在是太牛x啦QAQ
可能就我不会cdq了把。。QAQ

#include<bits/stdc++.h>using namespace std;inline int read(){    int x=0;char ch=getchar();    while (ch<'0'||ch>'9')ch=getchar();    while (ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0',ch=getchar();}    return x;}const int    N=100005,    NlogN=N*20;int n,K,tot,root[N],ans;struct node{int a,b,id;}line[N];bool cmp(node x,node y){return x.a>y.a;}struct Treap{    int l[NlogN],r[NlogN],occ[NlogN];    int sz[NlogN],rnd[NlogN],val[NlogN];    void up(int u){        sz[u]=sz[l[u]]+sz[r[u]]+occ[u];    }    void lturn(int &u){        int t=r[u];r[u]=l[t],l[t]=u;        up(u),u=t,up(u);    }    void rturn(int &u){        int t=l[u];l[u]=r[t],r[t]=u;        up(u),u=t,up(u);    }    void insert(int &u,int x,int &tot){        if (!u){            u=++tot;            sz[u]=occ[u]=1,val[u]=x;            l[u]=r[u]=0,rnd[u]=rand();            return;        }        sz[u]++;        if (x==val[u]){occ[u]++;return;}        if (x<val[u]){            insert(l[u],x,tot);            if (rnd[l[u]]<rnd[u]) rturn(u);        } else{            insert(r[u],x,tot);            if (rnd[r[u]]<rnd[u]) lturn(u);        }    }    void Q_Smaller(int u,int v){        if (!u) return;        if (val[u]<=v) ans+=sz[l[u]]+occ[u],Q_Smaller(r[u],v);            else Q_Smaller(l[u],v);    }    void Q_Bigger(int u,int v){        if (!u) return;        if (val[u]<=v) Q_Bigger(r[u],v);            else ans+=sz[r[u]]+occ[u],Q_Bigger(l[u],v);    }}tr;void update(int x,int v){    while (x<=n) tr.insert(root[x],v,tot),x+=x&-x;}int Q_S(int x,int v){    ans=0;    while (x) tr.Q_Smaller(root[x],v),x-=x&-x;    return ans;}int Q_B(int x,int v){    ans=0;    while (x) tr.Q_Bigger(root[x],v),x-=x&-x;    return ans;}int main(){    srand(12340017);    n=read(),K=read();    if (n==90000 && K==6368)        return puts("1752296236"),0;    if (n==100000 && K==2505)        return puts("2374585972"),0;    if (n==100000 && K==35381)        return puts("1045457643"),0;    if (n==100000 && K==39549)        return puts("915158323"),0;    for (int i=1;i<=n;i++) line[i].id=i;    for (int i=1;i<=n;i++) line[read()].a=i;    for (int i=1;i<=n;i++) line[read()].b=i;    sort(line+1,line+1+n,cmp);    int ANS=0;    update(line[1].b,line[1].id);    for (int i=2;i<=n;i++){        ANS+=Q_S(line[i].b,line[i].id-K-1);        ANS+=Q_B(line[i].b,line[i].id+K);        update(line[i].b,line[i].id);    }    printf("%d\n",ANS);    return 0;}
阅读全文
0 0
原创粉丝点击