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

code:
#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);
}
本文来自博客园,作者:北烛青澜,转载请注明原文链接:https://www.cnblogs.com/Multitree/articles/16996374.html
The heart is higher than the sky, and life is thinner than paper.
浙公网安备 33010602011771号