【刷题】【莫队】/【主席树】/【树状数组】HH的项链

记录一下我勇敢的尝试,和克子数据

我在题解区翻啊翻,都没有过的了的莫队,和主席树,

无奈只能看树状数组

思路都差不多:

维护区间,记录每一种在当前区间中的最后一个,

看>=l 的有多少

 

58分,莫队:

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
inline int read()
{
    int x=0; char c=getchar();
    while(c<'0' || c>'9' ) c=getchar();
    while(c>='0'&&c<='9' ) x=(x<<3)+(x<<1)+c-'0',c=getchar();
    return x;
}
inline void wr(int x)
{
    if(x>=10) wr(x/10);
    putchar(x%10+'0');
}
int n,q;
const int N=1e6+3,M=1000000;
int siz;
int d[N],cnt[M];

struct node
{
    int l,r,id;
    bool operator < (const node & o ) const
    { return r/siz==o.r/siz ?l<o.l : r/siz<o.r/siz; };
}ask[N];
int ans[N];

int as;
void add(int x)
{
    cnt[x]++;
    if(cnt[x]==1) as++;
}
void sub(int x)
{
    cnt[x]--;
    if(cnt[x]==0) as--;
}

int main()
{
    //input
    n=read();
    siz=500;
    for(int i=1;i<=n;i++) d[i]=read();
    
    q=read();
    for(int i=1;i<=q;i++) ask[i].l =read(),ask[i].r =read(),ask[i].id =i;
    sort(ask+1,ask+q+1);
    
    int ll=1,rr=0;
    for(int i=1;i<=q;i++)
    {
        while(rr<ask[i].r ) add(d[++rr]);
        while(ll>ask[i].l ) add(d[--ll]);
        while(rr>ask[i].r ) sub(d[rr--]);
        while(ll<ask[i].l ) sub(d[ll++]);
        ans[ask[i].id ]=as;
    }
    for(int i=1;i<=q;i++)
        wr(ans[i]),putchar('\n');
    
    return 0;
}
View Code

72分,主席树:

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
inline int read()
{
    int x=0;char c=getchar();
    while(c<'0' || c>'9' ) c=getchar();
    while(c>='0'&&c<='9' ) x=(x<<3)+(x<<1)+c-'0',c=getchar();
    return x;
}
inline void wr(int x)
{
    if(x>=10) wr(x/10);
    putchar(x%10+'0');
}

int n,q;
const int N=1e6+3,Lg=20,M=1000003;
int pre[M],nx[N];

int tot;
int root[N];
int xh[N*Lg],ls[N*Lg],rs[N*Lg],sz[N*Lg];
void insert(int l,int r,int &x,int y,int pos)
{
    x=++tot;
    sz[x]=sz[y]+1;
    if(l==r) return ;
    
    ls[x]=ls[y],rs[x]=rs[y];
    int mid=(l+r)>>1;
    if(pos<=mid) insert(l,mid,ls[x],ls[y],pos);
    else insert(mid+1,r,rs[x],rs[y],pos);
}
int query(int l,int r,int x,int y,int pos)
{
    if(l==r ) return sz[x]-sz[y];
    
    int mid=(l+r)>>1;
    if(pos<=mid) return query(l,mid,ls[x],ls[y],pos) + sz[rs[x]]-sz[rs[y]];
    else return query(mid+1,r,rs[x],rs[y],pos);
}

int main()
{
    //input
    n=read();
    for(int i=1;i<=n;i++) 
    {
        int x=read();
        if(pre[x]) nx[pre[x]]=i;
        pre[x]=i;
    }
    for(int i=1;i<=n;i++)
        if(nx[i]) insert(1,n+1,root[i],root[i-1],nx[i]);
        else insert(1,n+1,root[i],root[i-1],n+1);
    //区间中包含多少不同的贝壳,就是区间中有多少贝壳,他们的nx>r,
    //他们就是区间中每种贝壳的最后一个 
    
    q=read();
    int l,r;
    while(q--)
    {
        l=read(),r=read(); 
        wr( query(1,n+1,root[r],root[l-1],r+1)) ;
        putchar('\n');
    }
    return 0;
}
View Code

100分,树状数组:

#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
inline int read()
{
    int x=0;char c=getchar();
    while(c<'0' || c>'9' ) c=getchar();
    while(c>='0'&&c<='9' ) x=(x<<3)+(x<<1)+c-'0',c=getchar();
    return x;
}
inline void wr(int x)
{
    if(x>=10) wr(x/10);
    putchar(x%10+'0');
}

int n,q;
const int N=1e6+3,Lg=20,M=1000003;
int d[N];
struct node
{
    int l,r,id;
    bool operator < (const node & o ) const
    { return r<o.r; }
}ask[N];
int ans[N];

int in[M];
int tr[M];
int lowbit(int x)
{ return x&(-x); }
void add(int pos,int x)
{
    while(pos<=N)
        tr[pos]+=x,pos+=lowbit(pos);
}
int query(int pos)
{
    int as=0;
    while(pos>0)
        as+=tr[pos],pos-=lowbit(pos);
    return as;
}

int main()
{
    //input
    n=read();
    for(int i=1;i<=n;i++) 
        d[i]=read();
    
    q=read();
    for(int i=1;i<=q;i++)
        ask[i].l =read() ,ask[i].r =read() ,ask[i].id =i;
    sort(ask+1,ask+q+1);
    
    int pre=0;
    for(int i=1;i<=q;i++)
    {
        for(int j=pre+1;j<=ask[i].r ;j++)
        {
            if(in[d[j]])
                add(in[d[j]],-1);
            add(j,1),in[d[j]]=j;
        }
        pre=ask[i].r ;
        ans[ask[i].id ]=query(ask[i].r )-query(ask[i].l -1); 
    }
    for(int i=1;i<=q;i++)
        wr(ans[i] ),putchar('\n');
    return 0;
}
View Code

 

posted @ 2019-10-30 20:32  心若笺诗  阅读(162)  评论(0编辑  收藏  举报