玄关求调cdq分治!!!
查看原帖
玄关求调cdq分治!!!
581928
jasonliujiahua楼主2023/11/6 11:21

P3157

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e5+10,N=1e5;
int n,m,b[maxn],c[maxn],ans[maxn];
struct node
{
    int id,val,time;
}a[maxn];
inline void add(int x,int y)
{
    for(;x<=N;x+=(x&-x)) c[x]+=y;
}
inline int query(int x)
{
    int res=0;
    for(;x;x-=(x&-x)) res+=c[x];
    return res;
}
inline bool cmp1(node x,node y)
{
    return x.time>y.time;
}
inline bool cmp2(node x,node y)
{
    return x.id<y.id;
}
void init()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i].val;
        b[a[i].val]=i;
        a[i].id=i;
        a[i].time=m+1;
    }
    for(int i=1;i<=m;i++)
    {
        int x;
        cin>>x;
        a[b[x]].time=i;
    }
    sort(a+1,a+n+1,cmp1);
}
void cdq(int l,int r)
{
    if(l==r) return;
    int mid=(l+r)>>1;
    cdq(l,mid);
    cdq(mid+1,r);
    sort(a+l,a+mid+1,cmp2);
    sort(a+mid+1,a+r+1,cmp2);
    int i,j;
    for(i=mid+1;i<=r;i++)
    {
        for(j=l;j<=mid && a[j].id<a[i].id;j++) add(a[j].val,1);
        ans[a[i].time]+=query(N)-query(a[i].val);
    }
    for(int w=l;w<j;w++) add(a[w].val,-1);
    for(i=r;i>=mid+1;i--)
    {
        for(j=mid;j>=l && a[j].id>a[i].id;j--) add(a[j].val,1);
        ans[a[i].time]+=query(a[i].val-1);
    }
    for(int w=mid;w>j;w--) add(a[w].val,-1);
}
void output()
{
    for(int i=m;i;i--) ans[i]+=ans[i+1];
    for(int i=1;i<=m;i++)
    {
        cout<<ans[i]<<endl;
    }
}
void test()
{
    for(int i=1;i<=n;i++)
    {
        cout<<a[i].id<<" "<<a[i].val<<" "<<a[i].time<<endl;
    }
    for(int i=1;i<=m+1;i++)
    {
        printf("ans[%lld]=%lld\n",i,ans[i]);
    }
}
signed main()
{
    // freopen("1.in","r",stdin);
    // freopen("1.out","w",stdout);
    init();
    cdq(1,n);
    // test();
    output();
    return 0;
}
2023/11/6 11:21
加载中...