• A


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5919

    题意: 给一个区间,经过运算后会得到一个区间。然后问这个区间里面有几个个不同的数,假设不同的数有n个,

                然后将这个区间不同的数进行排序,输出第n/2个的在区间第一次出现的下标就可以了。

    思路:我这是主席树专题里的,肯定要往主席树想,题目要的是第一次出现的位置,所以可以从后往前建树。

              然后按照每个位置的下标进行维护,再来个数组避免重复就可以了,数组记得要开大点

    #include<iostream>
    #include<cmath>
    #include<stdio.h>
    #include<algorithm>
    #include<cstring>
    #include<map>
    #include<vector>
    using namespace std;
    int a[8000010];
    int root[2000010],lson[8000010],rson[8000010];
    int sum[8000010],top,fa[2000010];
    void init()
    {
        top = 0;
        memset(sum,0,sizeof(sum));
        memset(root,0,sizeof(root));
        memset(lson,0,sizeof(lson));
        memset(rson,0,sizeof(rson));
        for(int i=0;i<2000010;i++)
            fa[i]=-1;
    }
    void Update(int l,int r,int &now,int last,int pos,int x)
    {
        now=++top;
        lson[now]=lson[last];
        rson[now]=rson[last];
        sum[now]=sum[last]+x;
        if(l==r)
            return;
        int mid=(l+r)>>1;
        if(pos<=mid)
            Update(l,mid,lson[now],lson[last],pos,x);
        else
            Update(mid+1,r,rson[now],rson[last],pos,x);
    }
    
    int Query(int rt,int L,int R,int l,int r)
    {
        if(l<=L&&r>=R)
            return sum[rt];
        int mid=(L+R)>>1;
        int ans=0;
        if(l<=mid)
            ans+=Query(lson[rt],L,mid,l,r);
        if(r>mid)
            ans+=Query(rson[rt],mid+1,R,l,r);
        return ans;
    }
    int getpos(int rt,int l,int r,int k)
    {
        if(l==r)
            return l;
        int ans=sum[lson[rt]];
        int mid=(l+r)>>1;
        if(ans>=k)
            return getpos(lson[rt],l,mid,k);
        else
            return getpos(rson[rt],mid+1,r,k-ans);
    }
    int main()
    {
        int T,n,m;
        scanf("%d",&T);
        int u=0;
        while(T--)
        {
            init();
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            for(int i=n;i>=1;i--)
            {
                if(fa[a[i]]==-1)
                    Update(1,n,root[i],root[i+1],i,1);
                else
                {
                    Update(1,n,root[i],root[i+1],fa[a[i]],-1);
                    Update(1,n,root[i],root[i],i,1);
                }
                fa[a[i]] = i;
            }
            int ans = 0;
            printf("Case #%d:",++u);
            while(m--)
            {
                int l,r;
                scanf("%d%d",&l,&r);
                l = (l + ans) % n + 1;
                r = (r + ans) % n + 1;
                if(l > r)
                    swap(l,r);
                int k=(Query(root[l],1,n,l,r)+1)>>1;
                printf(" %d",ans=getpos(root[l],1,n,k));
            }
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    【转】 矩阵构造方法
    CODEVS1187 Xor最大路径 (Trie树)
    POJ2001 Shortest Prefixes (Trie树)
    CODEVS1079 回家 (最短路)
    CODEVS2144 砝码称重2 (哈希表)
    CODEVS1380 没有上司的舞会 (树形DP)
    JAVA 多态和异常处理作业——动手动脑以及课后实验性问题
    再读大道之简第七章第八章
    JAVA 接口与继承作业——动手动脑以及课后实验性问题
    再读大道至简第六章
  • 原文地址:https://www.cnblogs.com/zcb123456789/p/11939436.html
Copyright © 2020-2023  润新知