题解:P16923 [JLCPC 2026] 水晶城堡
Xie_Yu_Fei · · 题解
前言
本题被放在了集训 NOIP 模拟赛的 T1。
Solution
考虑对于一个给定序列
考虑对于
上式的含义是先在
注意到分母可以提出来:
进一步地,由于
显然这个式子和
直接莫队维护即可。
Code
#include<bits/stdc++.h>
#define int long long
#define YUANSHEN ios_base::sync_with_stdio(0);
#define QIDONG cin.tie(0);
#define inf 1e18
#define endl '\n'
#define mod 998244353
#define frein freopen("rune.in","r",stdin);
#define freout freopen("rune.out","w",stdout);
using namespace std;
const int maxn=1e6+10;
int n,q,pos[maxn],T,cnt[maxn],ans[maxn],now=0,a[maxn];
struct Node{
int L,R,idx;
friend bool operator <(Node i,Node j){return (pos[i.L]!=pos[j.L])?(pos[i.L]<pos[j.L]):(pos[i.R]<pos[j.R]);}
}Q[maxn];
void init(){
now=0;
for(int i=1;i<=n;i++)cnt[i]=0;
int k=sqrt(n),j=1;
for(int i=1;i<=k;i++)while(j<=i*k)pos[j++]=i;
while(j<=n)pos[j++]=k+1;
}
int Getinv(int a){
int res=1,x=mod-2;
for(;x;x>>=1,a=(a*a)%mod)if(x&1)res=res*a%mod;
return res;
}
void add(int i){now+=2*cnt[a[i]]+1,cnt[a[i]]++;}
void del(int i){now+=1-2*cnt[a[i]],cnt[a[i]]--;}
signed main(){
YUANSHEN QIDONG
frein freout
cin>>T;
while(T--){
cin>>n>>q; init();
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=q;i++)cin>>Q[i].L>>Q[i].R,Q[i].idx=i;
sort(Q+1,Q+1+q);
for(int i=1,L=1,R=0;i<=q;i++){
while(R<Q[i].R)add(++R);
while(R>Q[i].R)del(R--);
while(L<Q[i].L)del(L++);
while(L>Q[i].L)add(--L);
ans[Q[i].idx]=(1+(Q[i].R-Q[i].L+1)-now%mod*Getinv(Q[i].R-Q[i].L+1)%mod+mod)%mod;
}
for(int i=1;i<=q;i++)cout<<ans[i]<<endl;
}
return 0;
}
青紫紫黑的 NOIP 模拟赛好玩吗?