洛谷P6104 相同的数字

首先把 $a$ 排序。不难发现只有两种可能方案:把所有数改成 $a_n$,改成不小于 $a_n$ 的第一个质数。

对于每个数,把它改成大于它的第一个质数,再改成第二个……这些过程可以拆开来放在一起,对于短于 $\frac{c_2}{c_1}$ 的区间用第一种方案,更长的用第二种。

一些细节:如果 $a_n$ 不是质数,那么改成 $a_n$ 只能用第一种方案;过程总数可能很多,但区间长度不会超过154,所以用前缀和记一下就可以做到 $O(nloga_i+q)$。

#include<cstdio>
#include<algorithm>
#define For(i,A,B) for(i=(A);i<=(B);++i)
using namespace std;
typedef long long ll;
const int N=100050;
const int BUF=1<<23;
char rB[BUF],*rS,*rT,wB[BUF+50];
int wp=-1;
inline char gc(){return rS==rT&&(rT=(rS=rB)+fread(rB,1,BUF,stdin),rS==rT)?EOF:*rS++;}
inline void flush(){fwrite(wB,1,wp+1,stdout);wp=-1;}
inline int rd(){
    char c=gc();
    while(c<48||c>57)c=gc();
    int x=c&15;
    for(c=gc();c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c&15);
    return x;
}
short buf[25];
inline void wt(ll x){
    if(wp>BUF)flush();
    short l=-1;
    while(x>9){
        buf[++l]=x%10;
        x/=10;
    }
    wB[++wp]=x|48;
    while(l>=0)wB[++wp]=buf[l--]|48;
    wB[++wp]='\n';
}
bool f[10000020];
int p[670000],cnt,a[N],s[670000];
ll c[160],c2[160],sum[160],sum2[160];
int main(){
    int n=rd(),q=rd(),T=rd(),x,y,i,j,ps,t,tot=0;
    ll ans=0ll;
    For(i,1,n)a[i]=rd();
    sort(a+1,a+n+1);
    For(i,2,3162)if(!f[i])
        for(j=i*i;j<=10000019;j+=i)f[j]=1;
    For(i,2,10000019)if(!f[i])p[cnt++]=i;
    ps=lower_bound(p,p+cnt,a[n])-p;
    For(i,1,n)if((t=lower_bound(p,p+cnt,a[i])-p)<ps){
        ++s[t];
        if(a[i]<p[t])++c[p[t]-a[i]];
        tot+=a[n]-p[ps-1];
        ++c2[p[ps]-p[ps-1]];
    }else{
        tot+=a[n]-a[i];
        if(a[i]<p[ps])++c2[p[ps]-a[i]];
    }
    For(i,1,ps-1){
        c[p[i]-p[i-1]]+=s[i-1];
        s[i]+=s[i-1];
    }
    For(i,1,154){
        sum[i]=c[i]*i+sum[i-1];sum2[i]=(c2[i]+=c[i])*i+sum2[i-1];
        c[i]+=c[i-1];c2[i]+=c2[i-1];
    }
    while(q--){
        x=rd()^(T*(ans&(1<<17)-1));y=rd()^(T*(ans&(1<<17)-1));
        t=min(y/x,154);
        wt(ans=min((sum[t]+tot)*x+(c[154]-c[t])*y,sum2[t]*x+(c2[154]-c2[t])*y));
    }
    flush();
    return 0;
}
View Code

 

posted @ 2020-02-16 16:02  wangyuchen  阅读(168)  评论(0编辑  收藏  举报