Median——题解

题目大意

定义两个数列: S = { S 1 , S 2 S n } S 2 = { S 2 1 , S 2 2 , S 2 n }
其中
S i = ( P i i ) m o d     W P i 表示第 i 个素数)
S 2 i = S i + S i / 10 + 1

i = 1 n k + 1 M ( i , i + k 1 ) M ( L , R ) 表示 S 2 [ L , R ] 的中位数)

n , k , W <= 10000000 , 2 s

首先,筛出第 10000000 个素数?素数的分布是近似 l o g 的,所以第 10000000 个素数应近似为 200000000 (实际为 179424673 ),此时 l o g 级的筛素数都吃不消了,只能上高端线性欧拉筛+各种卡常:(然而还是要 1.5 s !!!

void make(){
    for(__R int i=2;i<=N;i+=(i&1)+1){
        if(!vis[i]){p[++p[0]]=i;if(p[0]==n) return;}
        for(__R int j=1;j<=p[0];j++){
            if(p[j]>N/i) break;
            vis[p[j]*i]=1;
            if(!(i%p[j])) break;
        }
    }
}

然后, O ( 1 ) 求区间中位数?
l o g 的做法有很多,写大小两个堆或直接上平衡树,但 0.5 s 你想干嘛。。
然后玄学的来了。。

“注意到这题的输入很诡异,其实可以当做是随机数据
那么随机数据满足分布均匀,也就是说可以假定,中位数的值变化也是常数级的
那么只要维护一个指针,挪动更新下中位数的位置就好了” ——摘自 S o l u t i o n

每次区间移动只更改两个元素,看起来也挺有道理的吧QWQ
然后就是写起来太像玄学的莫队了。。

#pragma GCC optimize(2) 
#include<cstdio>
#include<algorithm>
#define __R register
#define LL long long
using namespace std;
const int maxp=(1e7)+5,maxn=179424680,N=179424673;
int n,k,TT,p[maxp],C[maxp],A[maxp],hsh[maxp<<1];bool vis[maxn];LL Ans;
int Q;
void make(){
    for(__R int i=2;i<=N;i+=(i&1)+1){
        if(!vis[i]){p[++p[0]]=i;if(p[0]==n) return;}
        for(__R int j=1;j<=p[0];j++){
            if(p[j]>N/i) break;
            vis[p[j]*i]=1;
            if(!(i%p[j])) break;
        }
    }
}
int main(){
    scanf("%d%d%d",&n,&k,&TT),make();
    for(__R int i=1;i<=n;i++) C[i]=(LL)p[i]*i%TT,A[i]=C[i]+C[i/10+1];
    for(__R int i=1;i<k;i++) hsh[A[i]]++;
    int b1=-1,b2=-1,lst1=0,lst2=0,kk=k+1>>1;bool flg=(k&1);
    for(__R int i=k;i<=n;i++){
        hsh[A[i]]++,lst1+=(A[i]<=b1),lst2+=(A[i]<=b2);
        if(i>k) hsh[A[i-k]]--,lst1-=(A[i-k]<=b1),lst2-=(A[i-k]<=b2);
        while(lst1<kk) lst1+=hsh[++b1];
        while(lst2<kk+1) lst2+=hsh[++b2];
        while(lst1-hsh[b1]>=kk) lst1-=hsh[b1--];
        while(lst2-hsh[b2]>=kk+1) lst2-=hsh[b2--];
        if(flg) Ans+=b1+b1;else Ans+=b1+b2;
    }
    if(Ans&1) printf("%lld.5\n",Ans>>1);else printf("%lld.0\n",Ans>>1);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42403731/article/details/81837928
今日推荐