bzoj 2724: [Violet 6]蒲公英

2724: [Violet 6]蒲公英

Time Limit: 40 Sec   Memory Limit: 512 MB
Submit: 1278   Solved: 425
[ 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 Output

1
2
1

HINT


修正下:


n <= 40000, m <= 50000

Source



#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 40003
using namespace std;
int n,m,f[210][210],h[210][210],cnt,sum,t;
int a[N],p[N],b[N],tr[N],num[N],pos[N],q[N];
int head[N],tail[N];
int cmp(int x,int y)
{
  return b[x]<b[y];
}
void work()
{
  for (int i=1;i<=t;i++)
   {
   	memset(num,0,sizeof(num));
   	int l=(i-1)*cnt+1;
   	for (int j=l;j<=n;j++)
   	 {
   	   num[a[j]]++;
   	   if (!f[i][pos[j]]&&pos[j]!=i)
   	    {
   	      f[i][pos[j]]=f[i][pos[j]-1];
   	      h[i][pos[j]]=h[i][pos[j]-1];
   	    }
   	   if (num[a[j]]>f[i][pos[j]])
   	    {
   	      f[i][pos[j]]=num[a[j]];
   	      h[i][pos[j]]=b[j];
   	    }
   	   if (num[a[j]]==f[i][pos[j]])
   	    h[i][pos[j]]=min(h[i][pos[j]],b[j]);
   	 }
   }
}
int cmp1(int x,int y)
{
  return p[x]<p[y]||p[x]==p[y]&&x<y;
}
void work1()
{
  memset(p,0,sizeof(p));
  for (int i=1;i<=n;i++)
   p[i]=a[i],tr[i]=i;
  sort(tr+1,tr+n+1,cmp1);
  for (int i=1;i<=n;i++)
   if (a[tr[i]]!=a[tr[i-1]])
   {
    head[a[tr[i]]]=i;
    if (i-1)  tail[a[tr[i-1]]]=i-1;
   }
  tail[a[tr[n]]]=n;
  for (int i=1;i<=n;i++)
   q[i]=pos[tr[i]];
}
int query(int l,int r,int x)
{
  int k=0;
  int len=lower_bound(q+head[x],q+tail[x]+1,l)-q;
  int len1=upper_bound(q+head[x],q+tail[x]+1,r)-q;
  return len1-len;
}
int ask(int x,int y)
{
  int ansx=0; int anss=0; int ans=0;
  if (pos[x]==pos[y])
  {
   memset(num,0,sizeof(num));
   for (int i=x;i<=y;i++)
   {
    num[a[i]]++;
    if (ans<num[a[i]])
    {
      ans=num[a[i]];
      ansx=b[i]; 
    }
    else
    if (ans==num[a[i]])
     ansx=min(ansx,b[i]);
   }
  }
  else
  {
    int l=pos[x]+1; int r=pos[y]-1;
    ans=f[l][r]; ansx=h[l][r];
    memset(num,0,sizeof(num));
    for (int i=x;i<=pos[x]*cnt;i++)
     {
       if (!num[a[i]])
        num[a[i]]=query(pos[x]+1,pos[y]-1,a[i]);
       num[a[i]]++;
       if (num[a[i]]>ans)
        {
          ans=num[a[i]];
          ansx=b[i];
        }
       else
        if (num[a[i]]==ans)
         ansx=min(ansx,b[i]);
     }
    for (int i=(pos[y]-1)*cnt+1;i<=y;i++)
     {
       if (!num[a[i]])
        num[a[i]]=query(pos[x]+1,pos[y]-1,a[i]);
       num[a[i]]++;
       if (num[a[i]]>ans)
        {
          ans=num[a[i]];
          ansx=b[i];
        }
       else
        if (num[a[i]]==ans)
         ansx=min(ansx,b[i]);
     }
  }
  return ansx;
}
int main()
{
 scanf("%d%d",&n,&m);
 cnt=sqrt(n);
 for (int i=1;i<=n;i++)
  scanf("%d",&b[i]),p[i]=i,pos[i]=(i-1)/cnt+1;
 sort(p+1,p+n+1,cmp);
 for (int i=1;i<=n;i++)
  if (b[p[i]]!=b[p[i-1]])
   sum++,a[p[i]]=sum;
  else  a[p[i]]=sum;
 if (n%cnt) t=n/cnt+1;
 else t=n/cnt;
 work();
 work1();
 int k=0;
 for (int i=1;i<=m;i++)
 {
  int x,y; scanf("%d%d",&x,&y);
  x=(x+k-1)%n+1; y=(y+k-1)%n+1;
  if (x>y) swap(x,y);
  k=ask(x,y);
  printf("%d\n",k);
 }
}
数据生成器:

#include<cstdio>
#include<ctime>
#include<cstdlib>
#include<iostream>
using namespace std;
int main()
{
	freopen("input.txt","w",stdout);
	int n,m;
	n=40000;m=50000;
	srand(time(0));
	printf("%d %d\n",n,m);
	for (int i=1;i<=n;i++){
		int x=rand()*rand()%1000000000+1;
		cout<<x<<" ";
	}
	printf("\n");
	for (int i=1;i<=m;i++){
		int l=rand()*rand()%n+1;
		int r=rand()*rand()%n+1;
		cout<<l<<" "<<r<<endl;
	}
	return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值