2022牛客OI赛前集训营-提高组(第一场)

教练给我们打的离线(

数据分治忘删,多 solve 一次,明明复杂度 O(n^3) 偏偏不想压空间 敬重桥廊

不挂的话,70+100+50+50,挂了是 70+100+0+0/cy

推销一下 https://www.cnblogs.com/RuntimeErr/p/16757799.html

A

神笔题,不说了,没意义。

B

你会想要树形 dp,但是你发现其实儿子的子树(除去儿子)对当前答案没有任何影响,于是你会想到我们可以钦定点,然后仅保留这个点和这个点的儿子,钦定这些点是否跳,来得到答案。不重不漏考虑其他点乱跳,即我们只是选取了其一部分来观察这一部分对答案的贡献而已。

然后你会发现你要枚举子集,然后你发现是异或,然后典中典,枚举位,组合数一下就可以了。

#include <bits/stdc++.h> #define int long long #define pb push_back using namespace std; const int N=(int)(1e5+5),mod=(int)(1e9+7); vector<int>g[N]; int n,a[N],v[N],sz[N],ans; int fpow(int x,int y) { if(y<=0) return 1; int res=1; x%=mod; while(y) { if(y&1) res=res*x%mod; y>>=1; x=x*x%mod; } return res; } void dfs(int x,int ff) { int tot=0; sz[x]=1; for(int y:g[x]) { if(y==ff) continue ; dfs(y,x); sz[x]+=sz[y]; } for(int y:g[x]) { if(y==ff) continue ; v[++tot]=a[y]; } int qwq; if(x==1) qwq=fpow(2,n-1-tot); else qwq=fpow(2,n-2-tot); int res=0; if(x!=1) { for(int i=0;i<=30;i++) { int cnt1=0,cnt0=0; for(int j=1;j<=tot;j++) { if((v[j]>>i)&1) ++cnt1; else ++cnt0; } if(cnt1>=1) { res=(res+(1ll<<i)*cnt1%mod*(fpow(2,cnt0)-1)%mod)%mod; res=(res+(1ll<<i)*(fpow(2,cnt1-1)-cnt1)%mod*fpow(2,cnt0)%mod)%mod; } } } for(int i=0;i<=30;i++) { int cnt1=0,cnt0=0; for(int j=1;j<=tot;j++) { if((v[j]>>i)&1) ++cnt1; else ++cnt0; } if((a[x]>>i)&1) { res=(res+(1ll<<i)*(fpow(2,cnt0)-1)%mod)%mod; if(cnt1>=2) { res=(res+(1ll<<i)*(fpow(2,cnt1-1)-1)%mod*fpow(2,cnt0)%mod)%mod; } } else { if(cnt1) { res=(res+(1ll<<i)*fpow(2,cnt1-1)%mod*fpow(2,cnt0)%mod)%mod; } } } // cout<<x<<" "<<res*qwq<<'\n'; ans=(ans+res*qwq%mod)%mod; } signed main() { cin.tie(0); ios::sync_with_stdio(false); cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=2;i<=n;i++) { int x; cin>>x; g[x].pb(i); g[i].pb(x); } dfs(1,0); ans=(ans%mod+mod)%mod; cout<<ans; return 0; }

D

image

假如你不会线段树维护分段函数,假如你不会不带 log 的合并,建议跟我一样分块,但是块长和询问次数你要卡好。

显然我们有 Blogn=nB+B,解得 B=nlogn1,很厉害啊。

然后我试了一下 B=n,发现只能 55。充分说明了平衡的重要性(

#include <bits/stdc++.h> //#define int long long #define pb push_back using namespace std; const int N=(int)(3e5+5),M=5002; struct node { int op,x; }a[N]; struct nd { int L,R,b,lv,rv; nd() { } nd(int xL,int xR,int xb,int xlv,int xrv) { L=xL; R=xR; b=xb; lv=xlv; rv=xrv; } }val[M]; int n,q,bl,id[N],L[M],R[M]; int qry(int idx,int x) { for(int i=L[idx];i<=R[idx];i++) { if(a[i].op==1) x+=a[i].x; else if(a[i].op==2) x=min(x,a[i].x); else x=max(x,a[i].x); } return x; } nd query(int idx) { // [L,R]N :y=x+b int L=1,R=(int)(1e8),q1=qry(idx,1),q2=qry(idx,2),qR=qry(idx,R),qR1=qry(idx,R-1); if(q1!=q2) { //3/1 if(qR!=qR1) { int qwq=q1-1; return nd(1,(int)(1e8),qwq,0,0); } else { int l=1,r=(int)(1e8),res=0,qwq=qR; while(l<=r) { int mid=(l+r)>>1; if(qry(idx,mid)==qwq) res=mid,r=mid-1; else l=mid+1; } // if(x>=res) return qwq; int b=qry(idx,res-1)-(res-1); return nd(1,res-1,b,0,qR); } } else { if(qR!=qR1) { int l=1,r=(int)(1e8),res=0,qwq=q1; while(l<=r) { int mid=(l+r)>>1; if(qry(idx,mid)==qwq) res=mid,l=mid+1; else r=mid-1; } // if(x<=res) return qwq; int b=qry(idx,res+1)-(res+1); return nd(res+1,(int)(1e8),b,q1,0); } else { int l=1,r=(int)(1e8),qwq=q1,res=0; while(l<=r) { int mid=(l+r)>>1; if(qry(idx,mid)==qwq) res=mid,l=mid+1; else r=mid-1; } L=res+1; l=1; r=(int)(1e8); qwq=qR; res=0; while(l<=r) { int mid=(l+r)>>1; if(qry(idx,mid)==qwq) res=mid,r=mid-1; else l=mid+1; } R=res-1; // if(L<=x&&x<=R) { // qwq=qry(L)-L; // return x+qwq; // } // if(x<L) return qry(1); // if(x>R) return qry((int)(1e8)); qwq=qry(idx,L)-L; return nd(L,R,qwq,q1,qR); } } } int queryx(int idx,int x) { if(val[idx].L<=x&&x<=val[idx].R) return x+val[idx].b; if(x<val[idx].L) return val[idx].lv; return val[idx].rv; } int qryx(int x) { for(int i=1;i<=id[n];i++) { x=queryx(i,x); } return x; } signed main() { // freopen("1.in","r",stdin); // freopen("xgf.out","w",stdout); cin.tie(0); ios::sync_with_stdio(false); cin>>n; bl=sqrt(n/max(1,(int)log2(n)-1)); for(int i=1;i<=n;i++) { cin>>a[i].op>>a[i].x; id[i]=(i-1)/bl+1; } for(int i=1;i<=id[n];i++) L[i]=(i-1)*bl+1,R[i]=i*bl; for(int i=1;i<=id[n];i++) val[i]=query(i); cin>>q; while(q--) { int op; cin>>op; if(op!=4) { int x,y; cin>>x>>y; a[x].op=op; a[x].x=y; val[id[x]]=query(id[x]); } else { int x; cin>>x; cout<<qryx(x)<<'\n'; } } return 0; }

__EOF__

本文作者F x o r G
本文链接https://www.cnblogs.com/xugangfan/p/16757448.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   FxorG  阅读(167)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示