• bzoj2821: 作诗(Poetize)


    分块~好麻烦

    就像区间众数那题一样来

    用vector+二分来判区间每个数出现的个数

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    using namespace std;
    
    int n,a[110000];
    int block,st[110000];
    
    int f[410][410];
    int tim,ti[110000];bool v[101000];
    
    vector<int>vec[110000];int le[110000];
    int ifodd(int x,int y,int m)
    {
        if(x>y)return 0;
        int l=0,r=le[m]-1,as1=0;
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(vec[m][mid]<=x)
            {
                as1=mid+1;
                l=mid+1;
            }
            else r=mid-1;
        }
        l=0,r=le[m]-1;int as2=0;
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(vec[m][mid]<=y)
            {
                as2=mid+1;
                l=mid+1;
            }
            else r=mid-1;
        }
        return (as2==as1)?(-1):((as2-as1)&1);
    }
    
    int main()
    {
        freopen("poetize.in","r",stdin);
        freopen("poetize.out","w",stdout);
        int Q,C;
        scanf("%d%d%d",&n,&C,&Q); block=(int(sqrt(double(n+1))))+1;
        memset(le,0,sizeof(le));
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]); st[i]=(i-1)/block+1;
            vec[a[i]].push_back(i);le[a[i]]++;
        }
        
        tim=0;
        memset(ti,0,sizeof(ti));
        for(int i=1;i<=block;i++)
        {
            int j=i,cc=0; tim++;
            int be=(i-1)*block+1;
            for(int k=be;k<=n;k++)
            {
                if(st[k]!=st[k-1]&&k!=be)
                {
                    f[i][j]=cc;
                    j++;
                }
                
                if(tim!=ti[a[k]])
                {
                    ti[a[k]]=tim;
                    v[a[k]]=0;cc++;
                }
                v[a[k]]^=1;
                if(v[a[k]]==0)cc++;
                else cc--;
            }
            f[i][j]=cc;
        }
        
        //---------------init---------------------
        
        int l,r,ans=0;
        while(Q--)
        {
            scanf("%d%d",&l,&r);
            l=(l+ans)%n+1,r=(r+ans)%n+1;
            if(l>r)swap(l,r);
            
            ans=0; tim++;
            if(st[l]==st[r])
            {
                for(int k=l;k<=r;k++)
                {
                    if(tim!=ti[a[k]])
                    {
                        ti[a[k]]=tim;
                        v[a[k]]=0;ans++;
                    }
                    v[a[k]]^=1;
                    if(v[a[k]]==0)ans++;
                    else ans--;
                }
            }
            else
            {
                if(st[l]+1<=st[r]-1)ans=f[st[l]+1][st[r]-1];
                for(int k=l;k<=st[l]*block;k++)
                {
                    if(tim!=ti[a[k]])
                    {
                        ti[a[k]]=tim;
                        int d=ifodd(st[l]*block,(st[r]-1)*block,a[k]);
                        if(d<=0)
                        {
                            if(d==-1)ans++;
                            v[a[k]]=0;
                        }
                        else v[a[k]]=1;
                    }
                    v[a[k]]^=1;
                    if(v[a[k]]==0)ans++;
                    else ans--;
                }
                for(int k=(st[r]-1)*block+1;k<=r;k++)
                {
                    if(tim!=ti[a[k]])
                    {
                        ti[a[k]]=tim;
                        int d=ifodd(st[l]*block,(st[r]-1)*block,a[k]);
                        if(d<=0)
                        {
                            if(d==-1)ans++;
                            v[a[k]]=0;
                        }
                        else v[a[k]]=1;
                    }
                    v[a[k]]^=1;
                    if(v[a[k]]==0)ans++;
                    else ans--;
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }

     

  • 相关阅读:
    【POJ 2987 Firing】 最大权闭合子图
    【sgu176】有源汇有上下界的最大/最小流
    【HDU1263 水果】 STL之map应用经典好题
    【HDU1227 Fast Food】经典DP
    【hdu1043 && poj 1077】八数码问题
    有上下界的网络流问题
    【HDU4521】 dp思想+线段树操作
    miracl库下椭圆曲线方程常用函数使用入门
    函数指针
    python数据查询操作之 一场缺少db.commit()引发的血案……
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/9439326.html
Copyright © 2020-2023  润新知