【CDQ分治】代码输出全0求条
查看原帖
【CDQ分治】代码输出全0求条
481330
sunyizhe还是MC大佬楼主2025/7/1 23:07
//程序算法:CDQ分治
#include <bits/stdc++.h>
using namespace std;
const int N=4e5+10; // 修改为 n+m 级别

int n,m,c[N],ans[N];

struct Node{
    int time,id,v,op;
    friend bool operator < (const Node& x,const Node& y){
        if(x.time!=y.time)return x.time<y.time;
        if(x.v!=y.v)return x.v<y.v;
        return x.id<y.id;
    }
}a[N];

int lowbit(int x)
{
    return x&(-x);
}

void add(int x,int v)
{
    for(int i=x;i<=n+m;i+=lowbit(i)) // 修改上界为 n+m
        c[i]+=v;
}

int ask(int x)
{
    int ans=0;
    for(int i=x;i;i-=lowbit(i))
        ans+=c[i];
    return ans;
}

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);
    sort(a+mid+1,a+r+1);

    int i=l;
    for(int j=mid+1;j<=r;j++)
    {
        while(i<=mid&&a[i].v>a[j].v)
        {
            add(a[i].id,a[i].op);
            i++;
        }
        
        ans[a[j].time]+=ask(a[j].id)*a[j].op;
    }

    while((--i)>=l)add(a[i].id,-a[i].op);
    
    i=mid;
    for(int j=r;j>=mid+1;j--)
    {
        while(i>=l&&a[i].v<a[j].v)
        {
            add(a[i].id,a[i].op);
            i--;
        }
        ans[a[j].time]+=(ask(n+m)-ask(a[j].id))*a[j].op;
    }

    while((++i)<=mid)add(a[i].id,-a[i].op);
}

void fast_read()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
}

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    
    fast_read();

    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i].v;
        a[i].id=i,a[i].op=1,a[i].time=0;
    }

    for(int i=n+1;i<=n+m;i++)
    {
        cin>>a[i].v;
        a[i].id=i,a[i].op=-1,a[i].time=i-n;
    }

    CDQ(1,n+m);

    for(int i=1;i<=m;i++)
        cout<<ans[i]<<'\n';

    return 0;
}
2025/7/1 23:07
加载中...