题解 P7704 「MCOI-09」Greedy Deletion
设
如果
由于
这样的复杂度是
代码如下(码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#define pb push_back
#define sml(x,y) (x=min(x,y))
#define big(x,y) (x=max(x,y))
#define ll long long
#define db double
#define fo(i,x,y) for(register int i=x;i<=y;++i)
#define go(i,x,y) for(register int i=x;i>=y;--i)
using namespace std;
inline int read(){int x=0,fh=1; char ch=getchar(); while(!isdigit(ch)){if(ch=='-') fh=-1; ch=getchar();} while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0'; ch=getchar();} return x*fh;}
const int N=5e6+5,qlr=998244353,lim=20;
int pme[N],top,mn[N],e[N],pre[N],ok[N],ask[N],a[N],od[N/10],Ans[N/10],pw[N],_k;
inline int ksm(int x,int y){
int t=x,ans=1;
while(y){
if(y&1) ans=1ll*ans*t%qlr;
t=1ll*t*t%qlr;
y>>=1;
}
return ans;
}
void xxs(int n){
fo(i,2,n){
if(!ok[i]){
pme[++top]=i,mn[i]=pre[i]=i,e[i]=1;
pw[i]=ksm(i,_k);
}
fo(j,1,top){
int p=pme[j],k=i*p;
if(k>n) break;
ok[k]=1;
if(i%p) mn[k]=pre[k]=p,e[k]=1;
else{
mn[k]=p,pre[k]=pre[i]*p,e[k]=e[i]+1;
break;
}
}
}
}
bool cmp(int x,int y){return ask[x]<ask[y];}
int main(){
int T=read(),k=read(),n=read(),lst=2,ans=0;_k=k;
xxs(n);
fo(i,1,T) ask[i]=read(),od[i]=i;
sort(od+1,od+1+T,cmp);
fo(i,1,T){
fo(j,lst,ask[od[i]]){
int t=j;
while(t>1){
if(e[t]&1){
a[mn[t]]^=1;
if(a[mn[t]]) ans=(ans+pw[mn[t]])%qlr;
else ans=(ans-pw[mn[t]]+qlr)%qlr;
}
t/=pre[t];
}
}lst=ask[od[i]]+1;
Ans[od[i]]=ans;
}fo(i,1,T) printf("%d\n",Ans[i]);
return 0;
}