您的位置:首页 > 其它

bzoj 2724: [Violet 6]蒲公英

2016-03-31 16:50 381 查看

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

Vani原创

#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
,p
,b
,tr
,num
,pos
,q
;
int head
,tail
;
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;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: