smoj1987(cdq分治+离散化/数据结构)

来源:互联网 发布:耳机煲机软件 编辑:程序博客网 时间:2024/06/04 20:07

这题本来不想写的。
这两天用了我极大的精力码完了两个长长的程序,还在语文课美滋滋地想着博客题解怎么写。结果发现这两题解法本来就是错的。为了不感觉这两天什么都没做,就写这篇吧。
这里写图片描述
这里写图片描述

这题居然用multiset来统计某个数有多少个?离散化后用个桶就可以解决了。这个信息是可以加减合并的。
然后直接想cdq分治。这里二分出时间mid,核心就是处理出时间小于等于mid的修改对时间大于mid的询问的修改就好。

这里每个数字的询问和修改是独立的,我们就单独考虑一个数字。
问题就变成了在某个位置+1或-1,询问前缀和。
把时间离散化之后BIT就可以解决了。
觉得离散化代码比treap长的也可以打棵treap。

#include <iostream>#include <fstream>#include <algorithm>#include <cmath>#include <ctime>#include <cstdio>#include <cstdlib>#include <cstring>using namespace std;#define mmst(a, b) memset(a, b, sizeof(a))#define mmcp(a, b) memcpy(a, b, sizeof(b))typedef long long LL;const int N=100100;struct yy{    int tim,ops,x,num;}f[N],a[N],b[N];struct biu{    int num,x;}g[N];bool cmp(biu tu,biu hy){    return tu.x<hy.x;}int n,ans[N],mp[N];bool ok[N];void work(int hh,int tt,int l,int r){    if(hh>tt)    return;    if(l==r)    {        for(int i=hh;i<=tt;i++)        if(f[i].ops==0)        ans[f[i].num]+=mp[f[i].x];        else        mp[f[i].x]+=f[i].ops;        for(int i=hh;i<=tt;i++)        if(f[i].ops!=0)        mp[f[i].x]-=f[i].ops;        return;    }    int mid=(l+r)/2,l1=0,r1=0;    for(int i=hh;i<=tt;i++)    if(f[i].tim<=mid)    {        a[++l1]=f[i];        if(f[i].ops!=0)        mp[f[i].x]+=f[i].ops;    }    else    {        b[++r1]=f[i];        if(f[i].ops==0)        ans[f[i].num]+=mp[f[i].x];    }    for(int i=1;i<=l1;i++)    mp[a[i].x]-=a[i].ops;    for(int i=hh;i<=hh+l1-1;i++)    f[i]=a[i-hh+1];    for(int i=l1+hh;i<=tt;i++)    f[i]=b[i-hh-l1+1];    work(hh,hh+l1-1,l,mid);    work(hh+l1,tt,mid+1,r);    return;}int main(){    cin>>n;    for(int i=1;i<=n;i++)    {        int op;        scanf("%d",&op);        if(op==1)        f[i].ops=1;        if(op==2)        f[i].ops=-1;        if(op==3)        {            f[i].ops=0;            ok[i]=1;        }        scanf("%d%d",&f[i].tim,&f[i].x);        g[i].x=f[i].x;        g[i].num=i;        f[i].num=i;    }    sort(g+1,g+n+1,cmp);    f[0].x=-25;    for(int i=1;i<=n;i++)    if(g[i].x==g[i-1].x)    f[g[i].num].x=f[g[i-1].num].x;    else    f[g[i].num].x=f[g[i-1].num].x+1;    work(1,n,1,1000000000);    for(int i=1;i<=n;i++)    if(ok[i])    printf("%d\n",ans[i]);    return 0;}