NOIP2018模擬9.15總結
阿新 • • 發佈:2018-11-03
就是這樣
分數100+80+60=240
RANK1
暴力真是爽
T1題意
有N個點,M條邊,K個特殊點,邊權為1
求每個點到離他最遠的特殊點的最短距離
NK<=10000000
顯然暴力
T1程式碼
#include<bits/stdc++.h>
#define N 300001
using namespace std;
int i,j,k,l,n,m,tot,tov[N],b[N],a[N],x,y,next[N],last[N],dis[N],dl[N],head,tail;
void lian(int x,int y){tot++,tov[tot]=y ,next[tot]=last[x],last[x]=tot;}
void spfa(int x)
{
memset(dis,126,sizeof dis);
dis[x]=0,dl[1]=x,head=0,tail=1;
while(head<tail)
{
head++;
int i=dl[head];
for(j=last[i];j;j=next[j])
{
int y=tov[j];
if(dis[y]<=m)continue;
dis[y ]=dis[i]+1;
tail++;
dl[tail]=y;
}
}
for(int i=1;i<=n;i++)b[i]=max(b[i],dis[i]);
}
int main()
{
freopen("oasis.in","r",stdin);
freopen("oasis.out","w",stdout);
scanf("%d%d%d",&n,&m,&k);
for(i=1;i<=k;i++)scanf("%d",&a[i]);
for (i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
lian(x,y),lian(y,x);
}
for(i=1;i<=k;i++)
{
spfa(a[i]);
}
for(i=1;i<=n;i++)printf("%d ",b[i]);
}
T2題意
有N個點,點的度數為1或2,無重邊自環,不要求聯通, 求方案數,對998244353取膜
有大樣例
練習xjb猜公式的能力
T2程式碼
#include<bits/stdc++.h>
#define fo(i,x,y) for(int i=x;i<=y;i++)
#define mo 998244353
int n,x,y,z;
long long c[2001][2001],f[2001][2001],jc[3001],sum,a[3001];
using namespace std;
int main()
{
freopen("map.in","r",stdin);
freopen("map.out","w",stdout);
scanf("%d",&n);
fo(i,1,n){scanf("%d",&z);if(z==1)x++;else y++;}
if(x%2==1)
{
printf("0");
return 0;
}
x/=2;
fo(i,0,n)c[0][i]=1;
fo(i,1,n)fo(j,1,n)c[i][j]=(c[i][j-1]+c[i-1][j-1])%mo;
jc[0]=1;
fo(i,1,n)jc[i]=(jc[i-1]*i)%mo;
if(x==0)
{
a[0]=1;
fo(i,1,y)
{
fo(j,3,i)a[i]=(a[i]+a[i-j]*c[j-1][i-1]%mo*c[2][j-1]%mo*jc[j-3]%mo)%mo;
}
printf("%lld",a[y]);
return 0;
}
f[0][0]=1;
fo(i,1,y)
{
fo(j,3,i)f[0][i]=(f[0][i]+f[0][i-j]*c[j-1][i-1]%mo*c[2][j-1]%mo*jc[j-3]%mo)%mo;
}
fo(i,1,x)
{
f[i][0]=f[i-1][0]*(i*2-1)%mo;
fo(j,1,y)
{
f[i][j]=0;
fo(k,0,j)f[i][j]=(f[i][j]+f[i-1][j-k]*(2*i-1)%mo*c[k][j]%mo*jc[k]%mo)%mo;
}
}
printf("%lld ",f[x][y]);
}
T3題意
有一個長度為N的序列,權值在0~
以內
每次修改一個值,然後求編號最小的權值恰好等於它前面所有點的權值之和的點(好像有點亂)
每次修改一個值,如果一個點的權值等於他前面所有點的權值之和,那它就是“史上最大毒瘤”,找出編號最小的史上最大毒瘤
開O2
練習xjb
的能力
#include<bits/stdc++.h>
using namespace std;
int i,n,m,x,y,j,k,sum,ans,a[50001];
int main()
{
freopen("challenge.in","r",stdin);
freopen("challenge.out","w",stdout);
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)scanf("%d",&a[i]);
ans=2147483647;
for(i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
a[x]=y;
if(ans<x)
{
printf("%d\n",ans);
continue;
}
sum=k=0;
for(j=1;j<=n;j++)
{
if(a[j]==sum)
{
ans=j;
printf("%d\n",ans);
k=1;
break;
}
sum+=a[j];
}
if(k==0)
{
printf("-1\n");
ans=2147483647;
}
}
}