あいさか たいがblogAisaka_Taiga的博客
//https://img2018.cnblogs.com/blog/1646268/201908/1646268-20190806114008215-138720377.jpg

2022NOIP解题报告

2022NOIP解题报告

T1

一拿到题看着挺简单,但考试的时候做了三个小时,最后数组忘清空了100->1
我看他们的做法都比我的简单,也比我的快一点,但是我这个做法在考试的时候是可以A掉T1的。
首先需要两个前缀和来维护当前点向下(s1)和向右(s2)(均不包括自身)分别有几个连续的0。
考虑一下,如果要是想计算以当前点为C或F的左上角,如何利用这两个前缀和进行计算。
先说C;
首先要保证当前点不为1且右方连续的0有1个及以上,然后,我们可以根据样例得知,向下的连续零要大于等于2然后每一行能与第一行匹配的C的个数就是当前点s11,F也是同理,只是与C相比多了下面的一条线,处理好即可。

code:

Copy
#include<bits/stdc++.h> #define int long long #define P 998244353 #define endl '\n' #define N 1100 using namespace std; int T,id,n,m,C,F,ansc,ansf; int s1[N][N],s2[N][N],s3[N][N],s4[N][N]; char a[N][N]; void work1() { while(T--) { for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) s1[i][j]=s2[i][j]=s3[i][j]=s4[i][j]=0; ansc=0;ansf=0; cin>>n>>m>>C>>F; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>a[i][j]; if(C==0&&F==0) { cout<<"0 0"<<endl; continue; } for(int i=n;i>=1;i--) { int ccc=0; for(int j=m;j>=1;j--) { if(a[i][j]=='0')s1[i][j]=ccc++; else ccc=0; } } for(int j=m;j>=1;j--) { int ccc=0; for(int i=n;i>=1;i--) { if(a[i][j]=='0')s2[i][j]=ccc++; else ccc=0; } } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) for(int o=i+2;o<=i+s2[i][j];o++) s3[i][j]=(s3[i][j]+s1[o][j]*s1[i][j])%P, s4[i][j]=(s4[i][j]+s1[o][j]*(s1[i][j]*(s2[i][j]-o+i)%P))%P; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) ansc=(ansc+s3[i][j])%P, ansf=(ansf+s4[i][j])%P; } cout<<(ansc%P)<<" "; if(F==0) { cout<<0<<endl; continue; } cout<<(ansf%P)<<endl; } } signed main() { cin>>T>>id; work1(); return 0; }

T2

考试没看懂,打了半个多小时没打出来去看别的了。
爆零了

T3

考试看了一遍后感觉不如T4的部分分好拿,所以没有去花费太多时间。
考试得了0分。
image
code:

Copy
#include<bits/stdc++.h> using namespace std; template<typename T>void rd(T&x){ x=0;int f=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-48;c=getchar();} x*=f; } typedef long long ll; const int N=5e5+10,M=1e6+10,E=M*2; const ll mod=1e9+7; ll qpow(ll x,ll y){ ll z=1; while(y){ if(y&1)z=z*x%mod; x=x*x%mod; y>>=1; } return z; } const int half=qpow(2,mod-2); int n,m,deg[N]; struct T{ int e=1,n[E],t[E],h[N]; void lnk(int x,int y){ n[++e]=h[x]; t[e]=y; h[x]=e; } }g,h; int c,d[N],l[N]; int t,s[N]; int p,b[N],z[N]; void tarj(int x,int f){ d[x]=l[x]=++c; s[t++]=x; for(int i=g.h[x];i;i=g.n[i]){ int y=g.t[i]; if(!d[y]){ tarj(y,x); l[x]=min(l[x],l[y]); }else if(y!=f)l[x]=min(l[x],d[y]); } if(d[x]==l[x]){ ++p; do{ --t; b[s[t]]=p; ++z[p]; }while(s[t]!=x); } } ll dp[N],ans; void dfs(int x,int f){ dp[x]=qpow(2,z[x]-1); for(int i=h.h[x];i;i=h.n[i]){ int y=h.t[i]; if(y==f)continue; dfs(y,x); dp[x]=dp[x]*(dp[y]+1)%mod; } dp[x]=(dp[x]+mod-half)%mod; ans=(ans+dp[x])%mod; } int main(){ rd(n);rd(m); for(int i=1,u,v;i<=m;++i)rd(u),rd(v),g.lnk(u,v),g.lnk(v,u),++deg[u],++deg[v]; tarj(1,1); for(int x=1;x<=n;++x){ for(int i=g.h[x];i;i=g.n[i]){ int y=g.t[i]; if(b[x]!=b[y])h.lnk(b[x],b[y]); } } dfs(1,1); printf("%lld",(ans+dp[1])*qpow(2,m)%mod); }
posted @   北烛青澜  阅读(52)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示