$NOIP2014$ 题解报告
目录
$Luogu P1328$ 生活大爆炸版石头剪刀布$( √ )$
$Luogu P1351$ 联合权值$( √ )$
$Luogu P1941$ 飞扬的小鸟$( √ )$
$Luogu P2038$ 无线网络发射器选址$( √ )$
$Luogu P2296$ 寻找道路$( √ )$
$Luogu P2312$ 解方程$( √ )$
$Luogu P1328$ 生活大爆炸版石头剪刀布
模拟大水题
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define g() getchar() 7 #define rg register 8 #define go(i,a,b) for(rg int i=a;i<=b;i++) 9 #define back(i,a,b) for(rg int i=a;i>=b;i--) 10 #define db double 11 #define ll long long 12 #define il inline 13 #define pf printf 14 using namespace std; 15 int fr(){ 16 int w=0,q=1; 17 char ch=g(); 18 while(ch<'0'||ch>'9'){ 19 if(ch=='-') q=-1; 20 ch=g(); 21 } 22 while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=g(); 23 return w*q; 24 } 25 const int N=1e4+2; 26 int n1,n2,a[N],b[N]; 27 ll n,ans1,ans2,s1,s2; 28 int main(){ 29 //freopen("","r",stdin); 30 //freopen("","w",stdout); 31 scanf("%lld%d%d",&n,&n1,&n2); 32 go(i,1,n1) a[i]=fr();a[0]=a[n1]; 33 go(i,1,n2) b[i]=fr();b[0]=b[n2]; 34 rg int n3=n1*n2,x=n%n3; 35 rg ll y=n/n3; 36 go(i,1,n3){ 37 rg int A=a[i%n1],B=b[i%n2]; 38 if(A==0){ 39 if(B==1||B==4) ans2++; 40 if(B==2||B==3) ans1++; 41 } 42 if(A==1){ 43 if(B==2||B==4) ans2++; 44 if(B==0||B==3) ans1++; 45 } 46 if(A==2){ 47 if(B==0||B==3) ans2++; 48 if(B==1||B==4) ans1++; 49 } 50 if(A==3){ 51 if(B==0||B==1) ans2++; 52 if(B==2||B==4) ans1++; 53 } 54 if(A==4){ 55 if(B==2||B==3) ans2++; 56 if(B==0||B==1) ans1++; 57 } 58 if(i==x) s1=ans1,s2=ans2; 59 } 60 ans1=ans1*y+s1;ans2=ans2*y+s2; 61 pf("%lld %lld ",ans1,ans2); 62 return 0; 63 }
$Luogu P1351$ 联合权值
与每个点组合会对答案造成贡献的显然是当前节点的祖父、兄弟和孙子。根据乘法分配律,我们利用每个点的儿子的权值之和求出当前节点与其兄弟对答案的贡献。每一组祖父和孙子的贡献可以在深度较大的点处$*2$算出。要求最大值,主要难点在兄弟之间,这里可以贪心找每个节点的儿子中最大的两个
1 #include<bits/stdc++.h> 2 #define ri register int 3 #define ll long long 4 #define rl register ll 5 #define go(i,a,b) for(ri i=a;i<=b;i++) 6 #define back(i,a,b) for(ri i=a;i>=b;i--) 7 #define g() getchar() 8 #define il inline 9 #define pf printf 10 #define mem(a,b) memset(a,b,sizeof(a)) 11 #define E(i,x) for(ri i=hd[x];i;i=e[i].nxt) 12 #define t(i) e[i].to 13 using namespace std; 14 il int fr(){ 15 ri w=0,q=1;char ch=g(); 16 while(ch<'0'||ch>'9'){if(ch=='-')q=-1;ch=g();} 17 while(ch>='0'&&ch<='9')w=(w<<1)+(w<<3)+ch-'0',ch=g(); 18 return w*q; 19 } 20 const int mod=10007; 21 const int N=200002; 22 int n,w[N],hd[N],ed,son[N],f[N],ans,mx; 23 struct edge{ 24 int nxt,to; 25 }e[N<<1]; 26 il void build(ri x,ri y){e[++ed]=(edge){hd[x],y};hd[x]=ed;return;} 27 il void Tree(ri x,ri fa){ 28 f[x]=fa;ri mx1=0,mx2=0; 29 E(i,x){ 30 if(t(i)==fa)continue; 31 Tree(t(i),x);son[x]+=w[t(i)]; 32 if(son[x]>=mod)son[x]-=mod; 33 if(w[t(i)]>=mx1)mx2=mx1,mx1=w[t(i)]; 34 else if(w[t(i)]>mx2)mx2=w[t(i)]; 35 } 36 mx=max(mx,mx1*mx2); 37 return; 38 } 39 int main(){ 40 //freopen(".in","r",stdin); 41 //freopen(".out","w",stdout); 42 n=fr(); 43 go(i,1,n-1){ 44 ri x=fr(),y=fr(); 45 build(x,y);build(y,x); 46 } 47 go(i,1,n)w[i]=fr(); 48 Tree(1,0); 49 go(i,1,n){ 50 if(f[f[i]])ans=(ans+2*(w[i]*w[f[f[i]]]%mod)%mod)%mod,mx=max(mx,w[i]*w[f[f[i]]]); 51 if(f[i])ans=(ans+w[i]*(son[f[i]]-w[i])%mod)%mod; 52 } 53 pf("%d %d ",mx,ans); 54 return 0; 55 }