2021.8.12
2021.8.12
2021.8.12 模拟赛
目录:
T1.幻象
T2.树上摩托
T3.矩阵
T 1 : T1: T1:幻象
L
u
o
g
u
l
i
n
k
\textcolor{pink}{Luogu~link}
Luogu link
分析:
之前做过 赛时切
设
p
i
p_i
pi为到
i
i
i的期望长度
f
i
f_i
fi为到
i
i
i的期望分数
p
i
=
(
p
i
−
1
+
1
)
×
a
i
p_i=(p_{i-1}+1)\times a_i
pi=(pi−1+1)×ai
f
i
=
f
i
−
1
+
(
p
i
2
−
p
i
−
1
2
)
×
a
i
f_i=f_{i-1}+(p_i^2-p_{i-1}^2)\times a_i
fi=fi−1+(pi2−pi−12)×ai
平方相减可以化成
(
p
i
−
1
+
1
)
2
−
p
i
−
1
2
=
2
×
p
i
−
1
+
1
(p_{i-1}+1)^2-p_{i-1}^2=2\times p_{i-1}+1
(pi−1+1)2−pi−12=2×pi−1+1 直接平方相减也行
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1e6+5;
int n,a[N];
double f[N],p[N];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
p[i]=(p[i-1]+1)*a[i]/100;
}
for(int i=1;i<=n;i++)
f[i]=f[i-1]+(2*p[i-1]+1)*a[i]/100;
printf("%.1lf",f[n]);
return 0;
}
T 2 : T2: T2:树上摩托
分析:
计算子树大小
s
i
z
e
size
size 再枚举树大小
i
i
i 判断
s
i
z
e
size
size为
i
i
i的倍数的节点数量为
n
i
\frac{n}{i}
in即可
d
f
s
dfs
dfs会爆栈 要
b
f
s
bfs
bfs
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#pragma GCC optimize(2)
using namespace std;
const int N=1e6+5;
int n,tot,head[N],size[N],res,ans,cnt[N],fa[N],q[N];
struct node{
int to,next;
}a[N<<1];
void add(int x,int y)
{
a[++tot]=(node){y,head[x]};
head[x]=tot;
}
void bfs()
{
int Head=1,tail=1;
q[1]=1;
while(Head<=tail)
{
int x=q[Head++];
size[x]=1;
for(int i=head[x];i;i=a[i].next)
{
int qwq=a[i].to;
if(qwq==fa[x]) continue;
fa[qwq]=x;
q[++tail]=qwq;
}
}
for(int i=n;i>=1;i--)
{
int x=q[i];
for(int j=head[x];j;j=a[j].next)
{
int qwq=a[j].to;
if(qwq^fa[x]) size[x]+=size[qwq];
}
}
}
int main(){
scanf("%d",&n);
for(int i=1,x,y;i<n;i++)
{
scanf("%d%d",&x,&y);
add(x,y); add(y,x);
}
bfs();
for(int i=1;i<=n;i++)
cnt[size[i]]++;
for(int i=1;i<=n;i++)
{
res=0;
if(n%i!=0) continue;
for(int j=1;j<=n/i;j++)
res+=cnt[i*j];
if(res==n/i) ans++;
}
printf("%d",ans);
return 0;
}
T 3 : T3: T3:矩阵
分析:
将所有最小和谐矩阵加入堆
每次从堆中取出最小的和谐矩阵 扩展出最多四个新的和谐矩阵 即上下左右多
1
1
1行或
1
1
1列 注意判重 做
k
k
k次即可 最后
a
n
s
ans
ans要
u
l
l
ull
ull
就很好
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<set>
#pragma GCC optimize(2)
#include<cstring>
#define reg register
using namespace std;
typedef long long ll;
const int N=1005;
int n,m,Mina,Minb,k,a[N][N];
ll sum[N][N],ans;
struct Square{
int x,y,x2,y2;
ll Sum()const{return sum[x2][y2]-sum[x2][y-1]-sum[x-1][y2]+sum[x-1][y-1];}
bool operator <(Square b)const{
Square a=*this;
if(a.Sum()!=b.Sum()) return a.Sum()<b.Sum();
if(a.x!=b.x) return a.x<b.x;
if(a.y!=b.y) return a.y<b.y;
if(a.x2!=b.x2) return a.x2<b.x2;
if(a.y2!=b.y2) return a.y2<b.y2;
return 0;
}
};
set<Square> Q;
int main(){
scanf("%d%d%d%d%d",&n,&m,&Mina,&Minb,&k);
for(reg int i=1;i<=n;i++)
for(reg int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
for(reg int i=1;i<=n;i++)
for(reg int j=1;j<=m;j++)
sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j];
for(reg int i=1;i<=n-Mina+1;i++)
for(reg int j=1;j<=m-Minb+1;j++)
{
Square tmp=(Square){i,j,i+Mina-1,j+Minb-1};
Q.insert(tmp);
}
k--;
while(k--)
{
Square tmp=*Q.begin();
Q.erase(tmp);
if(tmp.x>1)
{
Square res=(Square){tmp.x-1,tmp.y,tmp.x2,tmp.y2};
Q.insert(res);
}
if(tmp.y>1)
{
Square res=(Square){tmp.x,tmp.y-1,tmp.x2,tmp.y2};
Q.insert(res);
}
if(tmp.x2<n)
{
Square res=(Square){tmp.x,tmp.y,tmp.x2+1,tmp.y2};
Q.insert(res);
}
if(tmp.y2<m)
{
Square res=(Square){tmp.x,tmp.y,tmp.x2,tmp.y2+1};
Q.insert(res);
}
}
Square ans=*Q.begin();
printf("%u",ans.Sum());
return 0;
}