直接模拟
由于是几百年前的代码了就懒得改了
QAQ
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
using namespace std;
#define ll long long
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int f[5][5]={0,0,1,1,0,
1,0,0,1,0,
0,1,0,0,1,
0,0,1,0,1,
1,1,0,0,0,};
int n,a,b,a_[200],b_[200];
int ans1,ans2;
int main()
{
cin>>n>>a>>b;
for(int i=1;i<=a;i++) a_[i%a]=read();
for(int i=1;i<=b;i++) b_[i%b]=read();
for(int i=1;i<=n;i++)
{
ans1+=f[a_[i%a]][b_[i%b]];
ans2+=f[b_[i%b]][a_[i%a]];
}
cout<<ans1<<' '<<ans2<<"\n";
}
对每个点统计贡献,要不在一条链上,要不跨过他的父亲节点。
对每个点统计孩子的权值最大值,权值最小值,和权值和。
dfs大法好
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
inline ll _() {
ll x=0,f=1; char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())
if(ch=='-')f=-f;
for(;ch>='0'&&ch<='9';ch=getchar())
x=x*10+ch-'0';
return x*f;
}
#define _ _()
const int mod=1e4+7;
const int N=200005;
struct Edge{ int to,nxt; }e[N<<1];
int n,head[N],cnt,mx[N][2],val[N],sum[N],f[N],ansmax;
ll anssum;
inline void insert(int u,int v) {
e[cnt]=(Edge){v,head[u]};
head[u]=cnt++;
}
inline void ins(int u,int v) {
insert(u,v);
insert(v,u);
}
inline void dfs(int x,int fa) {
f[x]=fa;
ansmax=max(ansmax,val[x]*val[f[fa]]);
anssum=(anssum+val[x]*val[f[fa]]*2%mod)%mod;
for(int i=head[x];~i;i=e[i].nxt)
if(e[i].to!=fa) {
sum[x]=sum[x]+val[e[i].to];
if(val[e[i].to]>mx[x][0]) swap(mx[x][0],mx[x][1]),mx[x][0]=val[e[i].to];
else if(val[e[i].to]>mx[x][1]) mx[x][1]=val[e[i].to];
dfs(e[i].to,x);
}
}
int main() {
n=_;
memset(head,-1,sizeof(head));
for(int i=1,u,v;i<n;i++)
u=_,v=_,ins(u,v);
for(int i=1;i<=n;i++)
val[i]=_;
dfs(1,0);
for(int i=1;i<=n;i++) {
ansmax=max(ansmax,mx[i][0]*mx[i][1]);
if(f[i]) anssum=(anssum+1ll*(sum[f[i]]-val[i])*val[i]%mod)%mod;
}
printf("%d %lld\n",ansmax,anssum);
}
咕咕咕