BZOJ2724: [Violet 6]蒲公英

2724: [Violet 6]蒲公英

Time Limit: 40 Sec  Memory Limit: 512 MB
Submit: 795  Solved: 248
[Submit][Status]

Description

Input

修正一下

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

Output

Sample Input

Sample Output

HINT

修正下:

n <= 40000, m <= 50000

Source

Vani原创

题解:

调了两小时发现居然是全局变量和局部变量重了QAQ。。。

先离散化

f[i][j]表示到 i 块结束,j 出现的次数

g[i][j]表示 i 块 到 j块 的众数

询问的时候如果 x和y处在同一或相邻的块内,暴力排序扫一遍

否则把 x到x所在块的最后和y所在块的开始到y的所有元素提取出来,加上他们在中间出现的次数,排序+扫一遍

代码:

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<algorithm>
  6 #include<iostream>
  7 #include<vector>
  8 #include<map>
  9 #include<set>
 10 #include<queue>
 11 #include<string>
 12 #define inf 1000000000
 13 #define maxn 40000+100
 14 #define maxm 200+50
 15 #define eps 1e-10
 16 #define ll long long
 17 #define pa pair<int,int>
 18 #define for0(i,n) for(int i=0;i<=n;i++)
 19 #define for1(i,n) for(int i=1;i<=n;i++)
 20 #define for2(i,x,y) for(int i=x;i<=y;i++)
 21 using namespace std;
 22 inline int read()
 23 {
 24     int x=0,f=1;char ch=getchar();
 25     while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
 26     while(ch>=‘0‘&&ch<=‘9‘){x=10*x+ch-‘0‘;ch=getchar();}
 27     return x*f;
 28 }
 29 int n,m,ans=0,block,a[maxn],c[maxn],d[maxn],pos[maxn],sum[maxn],f[maxm][maxn],g[maxm][maxm];
 30 struct rec{int x,id;}b[maxn];
 31 inline bool cmp(rec a,rec b)
 32 {
 33     return a.x<b.x;
 34 }
 35 void ask(int x,int y)
 36 {
 37     x=(x+ans-1)%n+1;y=(y+ans-1)%n+1;
 38     if(x>y)swap(x,y);
 39     int bx=pos[x],by=pos[y],cnt=0,tmp=0,xx=0;
 40     if(by-bx<=1)
 41     {
 42         for2(i,x,y)d[++cnt]=a[i];
 43         sort(d+1,d+cnt+1);
 44         for1(i,cnt)
 45          {
 46           tmp++;
 47           if(i==cnt||d[i]!=d[i+1])
 48            {
 49             if(tmp>xx||(tmp==xx&&d[i]<ans))xx=tmp,ans=d[i];
 50             tmp=0;
 51            }
 52          }
 53     }
 54     else
 55     {
 56         for2(i,x,bx*block)d[++cnt]=a[i];
 57         for2(i,(by-1)*block+1,y)d[++cnt]=a[i];
 58         sort(d+1,d+cnt+1);
 59         ans=g[bx+1][by-1];xx=f[by-1][ans]-f[bx][ans];
 60         for1(i,cnt)
 61          {
 62              tmp++;
 63              if(i==cnt||d[i]!=d[i+1])
 64              {
 65                  tmp+=f[by-1][d[i]]-f[bx][d[i]];
 66                  if(tmp>xx||(tmp==xx&&d[i]<ans))xx=tmp,ans=d[i];
 67                  tmp=0;
 68              }
 69          }
 70     }
 71     ans=c[ans];
 72     printf("%d\n",ans);
 73 }
 74 int main()
 75 {
 76     freopen("input.txt","r",stdin);
 77     freopen("output.txt","w",stdout);
 78     n=read();m=read();
 79     for1(i,n)b[i].x=read(),b[i].id=i;
 80     sort(b+1,b+n+1,cmp);
 81     int tot=0;
 82     for1(i,n)
 83     {
 84         if(i==1||b[i].x!=b[i-1].x)tot++;
 85         a[b[i].id]=tot;
 86         c[tot]=b[i].x;
 87     }
 88     block=floor(sqrt(n));
 89     for1(i,n)
 90      {
 91          pos[i]=(i-1)/block+1;
 92          sum[a[i]]++;
 93          if(i==n||i==pos[i]*block)for1(j,tot)f[pos[i]][j]=sum[j];
 94      }
 95     for1(i,pos[n])
 96      for2(j,i,pos[n])
 97       {
 98           ans=g[i][j-1];
 99           for2(k,(j-1)*block+1,min(j*block,n))
100           if(f[j][a[k]]-f[i-1][a[k]]>f[j][ans]-f[i-1][ans]||
101             (f[j][a[k]]-f[i-1][a[k]]==f[j][ans]-f[i-1][ans]&&a[k]<ans))ans=a[k];
102         g[i][j]=ans;
103       }
104     ans=0;
105     while(m--)ask(read(),read());
106     return 0;
107 }

时间: 2024-10-26 06:42:35

BZOJ2724: [Violet 6]蒲公英的相关文章

【分块】bzoj2724 [Violet 6]蒲公英

分块,离散化,预处理出: ①前i块中x出现的次数(差分): ②第i块到第j块中的众数是谁,出现了多少次. 询问的时候,对于整块的部分直接获得答案:对于零散的部分,暴力统计每个数出现的次数,加上差分的结果,尝试更新ans. 1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 int n,m,sum,sz,n

bzoj2724: [Violet 6]蒲公英(离散化+分块)

我好弱啊..这题调了2天QwQ 题目大意:给定一个长度为n(n<=40000)的序列,m(m<=50000)次询问l~r之间出现次数最多的数.(区间众数) 这题如果用主席树就可以不用处理一堆前缀和..蓝鹅我不会~T_T~. 把序列n分成sqrt(n)块,先把所有数离散化,预处理出poi[i][j]表示第i块到第j块的众数(即出现次数最多的数). 询问有两种情况: 第一种情况是l~r在某个块中,那么直接扫一遍求出众数,效率O(sqrt(n)). 第二种情况是l~r在多个块中,l在x块,r在y块,

bzoj2724: [Violet 6]蒲公英(分块)

传送门 md调了一个晚上最后发现竟然是空间开小了……明明算出来够的…… 讲真其实我以前不太瞧得起分块,觉得这种基于暴力的数据结构一点美感都没有.然而今天做了这道分块的题才发现分块的暴力之美(如果我空间没有开小就更美了) 我们先将整个数组分块,设块的大小为$T$ 我们先预处理出所有以块边界为端点的区间的答案,即$ans[L][R]$代表着第$L$块到第$R$块的序列所代表的答案.这个可以$O(n*n/T)$预处理 然后我们先将所有的数给离散化,然后对每一个值都开一个vector,记录这个值在数组中

【BZOJ2724】[Violet 6]蒲公英 分块+二分

[BZOJ2724][Violet 6]蒲公英 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 题解:分块还是练脑子啊~ 结论:一个区间的众数要么是区间中一个块的众数,要么是块外的任意

【BZOJ 2724】 2724: [Violet 6]蒲公英 (区间众数不带修改版本)

2724: [Violet 6]蒲公英 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 1908  Solved: 678 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 <= 4

BZOJ 2724: [Violet 6]蒲公英

2724: [Violet 6]蒲公英 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 1633  Solved: 563[Submit][Status][Discuss] 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 Outp

【BZOJ 2724】 [Violet 6]蒲公英

2724: [Violet 6]蒲公英 Time Limit: 40 Sec  Memory Limit: 512 MB Submit: 970  Solved: 319 [Submit][Status][Discuss] 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 Out

「Violet」蒲公英

「Violet」蒲公英 传送门 区间众数,强制在线. 分块经典题. 像这题一样预处理,然后就直接爆搞,复杂度 \(O(n \sqrt n)\) 参考代码: #include <algorithm> #include <cstdio> #include <cmath> #define rg register #define file(x) freopen(x".in", "r", stdin), freopen(x".ou

【bzoj2724】[Violet 6]蒲公英 分块+STL-vector

题目描述 输入 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1 输出 样例输入 6 3 1 2 3 2 1 2 1 5 3 6 1 5 样例输出 1 2 1 题解 分块+STL-vector 一个显而易见的结论:区间众数一定是一段连续的块的众数或块外的数,证明略(逃 先把数据离散化,然后分块预处理出f[i][j],表示从块i到块j的众数位置.具体实现的话直接开个桶存一下就好了. 然后考虑询问,整块的直接拿出来求一下出现次