【比賽記錄】2025CSP-S模擬賽23
| A | B | C | D | Sum | Rank |
|---|---|---|---|---|---|
| 40 | 8 | 20 | 15 | 83 | 9/22 |
A. origen
首先做前綴和,答案變為 \(\sum_{i=0}^{n-1}\sum_{j=i+1}^{n}a_i\oplus a_j\)。
然后拆位考慮,分別計算 \(a^2\) 和 \(2ab\)。對于 \(a_i\),第 \(j\) 位為 \(t\),對 \(a^2\) 的貢獻為 \(2^{2j}\times cnt_{j,t\oplus 1}\),其中 \(cnt\) 是 \(1\) 到 \(i-1\) 的一個計數器。\(2ab\) 是類似的。時間復雜度 \(O(n\log^2a_i)\)。
Code
#include<bits/stdc++.h>
#define ll long long
#define il inline
using namespace std;
namespace asbt{
const int maxn=2e5+5,mod=998244353;
int n,a[maxn],_2[45],cnt1[25][2],cnt2[25][25][2][2];
int main(){
ios::sync_with_stdio(0),cin.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
a[i]^=a[i-1];
// cout<<a[i]<<" ";
}
// cout<<"\n";
_2[0]=1;
for(int i=1;i<=40;i++){
_2[i]=_2[i-1]*2%mod;
}
for(int i=0;i<=18;i++){
cnt1[i][0]++;
for(int j=i+1;j<=18;j++){
cnt2[i][j][0][0]++;
}
}
int ans=0;
for(int i=1;i<=n;i++){
// for(int j=0;j<=18;j++){
// cout<<cnt[j][0]<<" ";
// }
// cout<<"\n";
// for(int j=0;j<=18;j++){
// cout<<cnt[j][1]<<" ";
// }
// cout<<"\n";
for(int j=0;j<=18;j++){
int t1=a[i]>>j&1;
(ans+=_2[j<<1]*1ll*cnt1[j][t1^1]%mod)%=mod;
cnt1[j][t1]++;
for(int k=j+1;k<=18;k++){
int t2=a[i]>>k&1;
(ans+=_2[j+k]*2ll*cnt2[j][k][t1^1][t2^1]%mod)%=mod;
cnt2[j][k][t1][t2]++;
}
}
// cout<<i<<": "<<ans<<"\n";
}
cout<<ans;
return 0;
}
}
int main(){return asbt::main();}
B. competition
設 \(i\) 前最后一個包含 \(j\) 的位置為 \(pre_{i,j}\),那么答案可以由總方案數減去重復的貢獻,即為:
\[\sum_{i=1}^{n}(r_i-l_i+1)\times i\times(n-i+1)-\sum_{j=l_i}^{r_i}pre_{i,j}\times(n-i+1)
\]
于是使用線段樹動態維護 \(pre_i\) 即可。需要卡常。是誰把代碼卡成一坨屎還需要放大時限的我不說了好吧
Code
#include<bits/stdc++.h>
#define ll long long
#define il inline
#define lid id<<1
#define rid id<<1|1
#define mid ((L+R)>>1)
using namespace std;
constexpr int maxn=1e6+5,mod=1e9+7,bufsz=1<<20;
char ibuf[bufsz],*p1=ibuf,*p2=ibuf;
#define getchar() (p1==p2&&(p2=(p1=ibuf)+fread(ibuf,1,bufsz,stdin),p1==p2)?EOF:*p1++)
il ll read(){
char ch=getchar();
while(ch<'0'||ch>'9'){
ch=getchar();
}
ll x=0;
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
}
return x;
}
#undef getchar
int sum[maxn<<3],tag[maxn<<3],llp[maxn],rrp[maxn];
ll pl[maxn],pr[maxn],lp[maxn<<3],rp[maxn<<3];
bool fp[maxn<<3];
struct node{
int x;
ll y;
node(int x=0,ll y=0):x(x),y(y){}
il bool operator<(const node &p)const{
return y<p.y;
}
il bool operator==(const node &p)const{
return y==p.y;
}
}hp[maxn<<1];
il int pls(int x,int y){
return x+y<mod?x+y:x+y-mod;
}
il int sub(int x,int y){
return x>=y?x-y:x-y+mod;
}
il void pushdown(int id){
fp[id]&&(tag[lid]=tag[id],fp[lid]=1,
sum[lid]=(rp[lid]-lp[lid]+1)%mod*tag[id]%mod,
tag[rid]=tag[id],fp[rid]=1,
sum[rid]=(rp[rid]-lp[rid]+1)%mod*tag[id]%mod,
fp[id]=0);
}
il void build(int id,int L,int R){
return lp[id]=hp[L].y,rp[id]=hp[R+1].y-1,!(L^R)?void():
(build(lid,L,mid),build(rid,mid+1,R));
}
il void upd(int id,int L,int R,int l,int r,int v){
return L>=l&&R<=r?(tag[id]=v,fp[id]=1,
sum[id]=(rp[id]-lp[id]+1)%mod*v%mod,void()):
(pushdown(id),l<=mid&&(upd(lid,L,mid,l,r,v),0)
,r>mid&&(upd(rid,mid+1,R,l,r,v),0)
,sum[id]=pls(sum[lid],sum[rid]),void());
}
il int query(int id,int L,int R,int l,int r){
return L>=l&&R<=r?sum[id]:(pushdown(id),
r<=mid?query(lid,L,mid,l,r):
l>mid?query(rid,mid+1,R,l,r):
pls(query(lid,L,mid,l,r),query(rid,mid+1,R,l,r)));
}
il int qpow(int x,int y=mod-2){
int res=1;
for(;y;y>>=1,x=x*1ll*x%mod){
(y&1)&&(res=res*1ll*x%mod);
}
return res;
}
int main(){
// freopen("competition4.in","r",stdin);
int n=read(),tot=0;
read();
for(int i=1u;i<=n;++i){
pl[i]=read(),pr[i]=read(),
hp[++tot]=node(i,pl[i]),
hp[++tot]=node(-i,pr[i]+1);
}
sort(hp+1,hp+tot+1);
int cnt=0;
ll lst=0;
for(int i=1u;i<=tot;++i){
hp[i].y!=lst&&++cnt,(hp[i].x>0?llp[hp[i].x]:rrp[-hp[i].x])=cnt,lst=hp[i].y;
}
tot=unique(hp+1,hp+tot+1)-hp-1;
build(1,1,tot-1);
// puts("666");
int ans=0;
for(int i=1u,l,r;i<=n;++i){
l=llp[i],r=rrp[i]-1,
ans=sub(pls(ans,(pr[i]-pl[i]+1)%mod*i%mod*(n-i+1)%mod),query(1,1,tot-1,l,r)*1ll*(n-i+1)%mod),
upd(1,1,tot-1,l,r,i);
}
// cout<<ans<<"\n";
printf("%lld",ans*1ll*qpow(n*1ll*(n+1)/2%mod)%mod);
return 0;
}

浙公網安備 33010602011771號