WC2024 游记&题解
DAY -2
篮球,乒乓球,羽毛球,足球,gen,开幕式,gen,睡觉
DAY -1
冬眠,gen,冬眠,足球,乒乓球,gen,哦论文交流还挺有意思,gen,睡觉
DAY 0
选讲ez,gen,懒得听课了,羽毛球,gen,睡觉
DAY 1
T1 怎么那么傻逼啊。
T2 怎么那么傻逼啊。
T3 好神秘。T3 好神秘。哦我会特殊性质。
T3 好神秘。T3 好神秘。哦我会 m=1 了。哦我会
哦我会
然后再线段树合并一下。
开摆了。100+100+85
查分,没挂
听评讲,怎么直接跳过划分等价类的部分了。
诶是不是直接哈希就行了??????唐完了。
坤皇指出这个划分等价类在 CF1830C 里也有,而且我当时写的是
题解
T1
正着一遍背包,倒着一遍背包
T2
线段树优化 dp 即可
T3
思考
对于每个节点,你发现我们必须得知道
于是只有 3 种状态,直接 dp 即可。
进一步思考
更进一步的,你发现可能的
怎么优化到
问:怎么快速区分不同的
错误答案:这不是我们 qoj 5425 吗,你维护一下双向链表用线段树维护一下再启发式分裂一下!
正确答案:哈希即可。
贴个后来写的代码
#include<bits/stdc++.h>
using namespace std;
const int mod=998244353;
int n,X[200100],m,step;
#define ull unsigned long long
ull cf[200100],qc[200100];
int ls[12010000],rs[12001000],T[401000],f[400100],ne,cn,su[12010000];
int tg[12001000];
mt19937 rnd(time(0));
void up(int &o,int l,int r,int x){
o=++cn,tg[o]=su[o]=1;
if(l==r)return;
int mid=(l+r)>>1;
if(x<=mid)up(ls[o],l,mid,x);
else up(rs[o],mid+1,r,x);
}
int px,py,so;
void ad(int x,int z){if(!x)return;tg[x]=1ll*tg[x]*z%mod;su[x]=1ll*su[x]*z%mod;}
void pd(int x){ad(ls[x],tg[x]),ad(rs[x],tg[x]),tg[x]=1;}
int merge(int x,int y,int l,int r){
if(!x&&!y)return 0;
if(!x||!y){
if(!x)ad(y,px);else ad(x,py);
return x+y;
}
if(l==r){
(so+=1ll*su[x]*su[y]%mod)%=mod;
su[x]=(1ll*su[x]*py+1ll*su[y]*px+1ll*su[x]*su[y])%mod;
return x;
}
pd(x),pd(y);int mid=(l+r)>>1;
ls[x]=merge(ls[x],ls[y],l,mid);
rs[x]=merge(rs[x],rs[y],mid+1,r);
su[x]=(su[ls[x]]+su[rs[x]])%mod;
return x;
}
int dfs(int l,int r){
int u=++ne;
if(l+1==r){
int o=lower_bound(qc+1,qc+m+1,cf[l])-qc;
f[u]=1;up(T[u],1,m,o);return u;
}
int mi=X[++step],ls=dfs(l,mi),rs=dfs(mi,r);
px=f[ls],py=f[rs],f[u]=2ll*px*py%mod;
(f[u]+=1ll*px*su[T[rs]]%mod)%=mod;
(f[u]+=1ll*py*su[T[ls]]%mod)%=mod;
so=0,T[u]=merge(T[ls],T[rs],1,m);
(f[u]+=so)%=mod;
return u;
}
int ask(int p,int l,int r,int x){
if(!p)return 0;if(l==r)return su[p];
pd(p);int mid=(l+r)>>1;
if(x<=mid)return ask(ls[p],l,mid,x);
return ask(rs[p],mid+1,r,x);
}
int main(){
int md;
scanf("%d%d",&n,&md);
for(int i=1;i<n;i++)scanf("%d",&X[i]);
for(int i=1,l,r;i<=md;i++){
scanf("%d%d",&l,&r);ull e=rnd()*rnd()*rnd();
cf[l]^=e,cf[r]^=e;
}
for(int i=1;i<n;i++)cf[i]^=cf[i-1];
for(int i=0;i<n;i++)qc[++m]=cf[i];sort(qc+1,qc+m+1);m=unique(qc+1,qc+m+1)-qc-1;
dfs(0,n);
int ans=f[1];
for(int i=1;i<=m;i++)if(qc[i]==0)(ans+=ask(T[1],1,m,i))%=mod;
return printf("%d",ans),0;
}