zoukankan      html  css  js  c++  java
  • 算法复习——分块算法

    题目:

    Description

    Input

    修正一下

    l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1

    Output

    Sample Input

    6 3
    1 2 3 2 1 2
    1 5
    3 6
    1 5

    Sample Output

    1
    2
    1

    HINT


    修正下:


    n <= 40000, m <= 50000

    Source

    题解:

     

    题解如上·····一个分块模板题打了我2个小时·····不得不说代码能力和专注度还不够·····另外还学到了节约复杂度和空间的好方法···(具体见getans中的tot是如何每次重新变为1的)

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<ctime>
    #include<cctype>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    const int N=4e4+5;
    int visit[N],tim,n,m,num[N],cnt[N][205],ans[205][205],tot[N],temp[N],id[N],s,idx[N],len,tots,Left[N],Right[N];
    bool jud[N];
    inline int R()
    {
      char c;int f=0;
      for(c=getchar();c<'0'||c>'9';c=getchar());
      for(;c<='9'&&c>='0';c=getchar())
        f=(f<<3)+(f<<1)+c-'0';
      return f;
    }
    inline void pre()
    {
      sort(temp+1,temp+n+1);
      len=unique(temp+1,temp+n+1)-temp-1;
      for(int i=1;i<=n;i++)
      {  
        int t=num[i];
        num[i]=lower_bound(temp+1,temp+len+1,num[i])-temp;
        idx[num[i]]=t;
      }  
      //离散化-------------------------------------------------------
      s=(int)sqrt(n);
      tots=0;
      for(int i=1;i<=n;i++)
      {
        if(i%s==0)  id[i]=tots,Right[tots]=i,jud[i]=true;  
        else if(i%s==1)  id[i]=++tots,Left[tots]=i;
        else id[i]=tots;
      }
      Right[tots]=n,jud[n]=1;
     //分块------------------------------------------------
      for(int i=1;i<=n;i++)
        cnt[num[i]][id[i]]++;      
      for(int i=2;i<=tots;i++)
        for(int j=1;j<=len;j++)
          cnt[j][i]+=cnt[j][i-1];
      //统计cnt------------------------------------------ 
      for(int i=1;i<=tots;i++)
      {
        int maxx=0,anss=1e+8;  
        memset(tot,0,sizeof(tot));
        for(int j=Left[i];j<=n;j++)
        {
          tot[num[j]]++;
          if(tot[num[j]]>maxx||(tot[num[j]]==maxx&&num[j]<anss))  maxx=tot[num[j]],anss=num[j];
          if(jud[j]==true)  ans[i][id[j]]=anss; 
        }
      }
        //统计ans------------------------------------------ 
    }
    inline int getans(int a,int b)
    {
      tim++;
      if(b-a+1<2*s)
      {
        int maxx=0,anss=1e+8;
        for(int i=a;i<=b;i++)
        {
          if(visit[num[i]]!=tim)  visit[num[i]]=tim,tot[num[i]]=1;
          else tot[num[i]]++;
          if(tot[num[i]]>maxx||((tot[num[i]]==maxx)&&num[i]<anss))
            maxx=tot[num[i]],anss=num[i];
        }
        return idx[anss];
      }
      else
      {  
        int lefts,rights;
        if(a%s==1)  lefts=id[a];
        else lefts=id[a]+1;
        if(b%s==0)  rights=id[b];
        else rights=id[b]-1;
        int anss=ans[lefts][rights],maxx=cnt[anss][rights]-cnt[anss][lefts-1];
        for(int i=a;i<Left[lefts];i++)
        {
          if(visit[num[i]]!=tim)  visit[num[i]]=tim,tot[num[i]]=1;
          else tot[num[i]]++;
          if(tot[num[i]]+cnt[num[i]][rights]-cnt[num[i]][lefts-1]>maxx||((tot[num[i]]+cnt[num[i]][rights]-cnt[num[i]][lefts-1]==maxx)&&num[i]<anss))
            maxx=tot[num[i]]+cnt[num[i]][rights]-cnt[num[i]][lefts-1],anss=num[i];
        }
        for(int i=Right[rights]+1;i<=b;i++)
        {
          if(visit[num[i]]!=tim)  visit[num[i]]=tim,tot[num[i]]=1;
          else tot[num[i]]++;
          if(tot[num[i]]+cnt[num[i]][rights]-cnt[num[i]][lefts-1]>maxx||((tot[num[i]]+cnt[num[i]][rights]-cnt[num[i]][lefts-1]==maxx)&&num[i]<anss))
            maxx=tot[num[i]]+cnt[num[i]][rights]-cnt[num[i]][lefts-1],anss=num[i];
        }
        return idx[anss];
      }
    }
    int main()
    {
      //freopen("a.in","r",stdin);
      n=R(),m=R(); 
      for(int i=1;i<=n;i++)
      {  
        num[i]=R();temp[i]=num[i];
      }
      pre();
      int a,b,t=0;
      for(int i=1;i<=m;i++)
      {
        a=R(),b=R();
        a=(a+t-1)%n+1;
        b=(b+t-1)%n+1;
        if(a>b)  swap(a,b);
        t=getans(a,b);
        printf("%d
    ",t);
      }
      return 0;
    }
  • 相关阅读:
    CefSharp.v49.0.1浏览器控件完全WPF版,实现禁止弹出新窗口,在同一窗口打开链接,并且支持带type="POST" target="_blank"的链接
    C#动态调用WebService
    WPF实现窗体中的悬浮按钮
    Oracle树结构查询按层级排序
    WPF自定义TabControl样式
    WPF自定义Window窗体样式
    C# 实现图片压缩
    C# 图片反色处理 图片夜间模式
    C#中多线程中变量研究
    EasyNetQ操作RabbitMQ(高级消息队列)
  • 原文地址:https://www.cnblogs.com/AseanA/p/7506113.html
Copyright © 2011-2022 走看看