• 巴蜀3540 -- 【Violet 6 最终话】蒲公英


    Description

      原题的时间限制是 2s . 


    亲爱的哥哥:
      你在那个城市里面过得好吗?
      我在家里面最近很开心呢。昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多小朋友也被它杀掉了。我觉得把那么可怕的怪物召唤出来的那个坏蛋也很坏呢。不过奶奶说他是很难受的时候才做出这样的事的……
      最近村子里长出了一大片一大片的蒲公英。一刮风,这些蒲公英就能飘到好远的地方了呢。我觉得要是它们能飘到那个城市里面,让哥哥看看就好了呢!
      哥哥你要快点回来哦!
    爱你的妹妹 Violet

      Azure 读完这封信之后微笑了一下。
      “蒲公英吗……”
      
      
      在乡下的小路旁种着许多蒲公英,而我们的问题正是与这些蒲公英有关。
      为了简化起见,我们把所有的蒲公英看成一个长度为 n 的序列 (a1, a2, a3, ..., an),其中 ai 为一个正整数,表示第 i 棵蒲公英的种类编号。
      而每次询问一个区间[lr],你需要回答区间里出现次数最多的是哪种蒲公英,如果有若干种蒲公英出现次数相同,则输出种类编号最小的那个。
      注意,你的算法必须是在线的。

    Input

      第一行两个整数 nm,表示有 n 株蒲公英,m 次询问。
      接下来一行 n 个空格分隔的整数 ai,表示蒲公英的种类。
      再接下来 m 行每行两个整数 l0, r0,我们令上次询问的结果为 x(如果这是第一次询问,则 x = 0)。
      令 l = (l0 + x - 1) mod n + 1, r = (r0 + x - 1) mod n + 1,如果 l > r,则交换 lr
      最终的询问区间为[lr]。

    Output

      输出 m 行。每行一个整数,表示每次询问的结果。

    Sample Input

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

    Sample Output

    1 2 1

    Hint

      对于 20% 的数据,保证 1 ≤ nm ≤ 3000 。
      对于 100% 的数据,保证 1 ≤ n ≤ 40000,1 ≤ m ≤ 50000,1 ≤ ai ≤ 109 。

    Source

    Violet 6 最终话

    区间求众数,强制在线。

    分块处理,求出每一块区间的众数。对于一次询问的区间,其中众数要么是中间大块的众数,要么是两边小块中的数。

    扫描所求区间中的边缘小块,求其中每个数在区间内的出现次数,找出次数最多的就是区间众数了。

    求数的出现次数,可以预先用vector或者普通数组存这个数在序列中的每一个出现位置,然后二分查找即可。

    不管什么算法,逢二分必挂的被动技能又强行发动了,调二分调了半小时……

    用时比别人多了10000+ms,也是迷。

      1 /*by SilverN*/
      2 #include<iostream>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cstdio>
      6 #include<cmath>
      7 #include<vector>
      8 #include<map>
      9 using namespace std;
     10 const int mxn=50010;
     11 const int block=180;
     12 int read(){
     13     int x=0,f=1;char ch=getchar();
     14     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     15     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
     16     return x*f;
     17 }
     18 int n,m;
     19 //
     20 vector<int>pos[mxn];//数字出现位置 
     21 int v[mxn];//离散化标号对应的数字 
     22 map<int,int>mp;int mct=0;//数字对应的离散化标号 
     23 //
     24 int f[510][510];
     25 int b[mxn];//分块 
     26 //
     27 int a[mxn];
     28 int cnt[mxn];
     29 void init(int x){
     30     memset(cnt,0,sizeof cnt);
     31     int i,j;
     32     int mx=0,num=0;
     33     for(i=(x-1)*block+1;i<=n;i++){
     34         cnt[v[i]]++;
     35         if(cnt[v[i]]>mx || (cnt[v[i]]==mx && a[i]<num)){
     36             mx=cnt[v[i]];
     37             num=a[i];
     38         }
     39         f[x][b[i]]=num;
     40     }
     41     return;
     42 }
     43 int find(int x,int L,int R){
     44 /*    x=mp[x];
     45     int t=upper_bound(pos[x].begin(),pos[x].end(),R)-lower_bound(pos[x].begin(),pos[x].end(),L);
     46     return t;*/
     47     x=mp[x];
     48     int l=0,r=pos[x].size()-1;
     49     int ansl,ansr;
     50     while(l<=r){
     51         int mid=(l+r)>>1;
     52         if(pos[x][mid]<=R)l=mid+1;
     53         else r=mid-1;
     54     }
     55     ansr=l;
     56     l=0,r=pos[x].size()-1;
     57     while(l<=r){
     58         int mid=(l+r)>>1;
     59         if(pos[x][mid]<L)l=mid+1;
     60         else r=mid-1;
     61     }
     62     ansl=l;
     63 //    printf("ask:%d res:%d %d
    ",x,ansl,ansr);
     64     return ansr-ansl;
     65 }
     66 int query(int l,int r){
     67     int mxnum=f[b[l]+1][b[r]-1];
     68     int mx=find(mxnum,l,r);
     69     int i,j;
     70     int ed=min(b[l]*block,r);
     71     for(i=l;i<=ed;i++){
     72         int tmp=find(a[i],l,r);
     73         if(tmp>mx || (tmp==mx && a[i]<mxnum)){
     74             mx=tmp; mxnum=a[i];
     75         }
     76     }
     77     if(b[l]!=b[r])
     78       for(i=(b[r]-1)*block+1;i<=r;i++){
     79           int tmp=find(a[i],l,r);
     80         if(tmp>mx || (tmp==mx && a[i]<mxnum)){
     81             mx=tmp; mxnum=a[i];
     82         }
     83       }
     84     return mxnum;
     85 }
     86 int main(){
     87     n=read();m=read();
     88     int i,j;
     89     for(i=1;i<=n;i++){
     90         a[i]=read();
     91         if(!mp[a[i]])mp[a[i]]=++mct;
     92         v[i]=mp[a[i]];
     93         pos[v[i]].push_back(i);
     94     }
     95     for(i=1;i<=n;++i){b[i]=(i-1)/block+1;}
     96     for(i=1;i<=b[n];i++){init(i);}
     97     int x=0;
     98     int ql,qr;
     99     while(m--){
    100         ql=read();qr=read();
    101         ql=(ql+x-1)%n+1;
    102         qr=(qr+x-1)%n+1;
    103         if(ql>qr)swap(ql,qr);
    104         x=query(ql,qr);
    105         printf("%d
    ",x);
    106     }
    107     return 0;
    108 }
  • 相关阅读:
    SQL调用另一台服务器的表及存储过程(SQL函数openrowset()的使用以及相关问题处理)
    解决SQL Server 阻止了对组件Ad Hoc Distributed Queries访问的方法
    sql server exec 参数的传递
    c#修改webservice 的地址和端口(修改配置文件)
    JS转换HTML转义符,编码及解码
    nginx使用ssl模块配置支持HTTPS访问,腾讯云申请免费证书
    thinkcmf 相关
    ThinkJS 开发node后端 使用 简介
    linux复制指定目录下的全部文件到另一个目录中
    谷歌地图,国内使用Google Maps JavaScript API,国外业务
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/5937144.html
Copyright © 2020-2023  润新知