代碼未經測試僅供參考
C題
正常寫的話就組合數搞一搞
但是不取模,那麼問題就有趣起來了
衆所周知,Σc(奇數,sum)=Σ(偶數,sum),是很對稱的,所以我剛開始猜了每個點的貢獻只有1或-1,試了幾個菊花圖後發現貢獻和兒子數量有關:a[x]*(1-x的兒子數量)
找找規律:
#include <bits/stdc++.h> using namespace std; typedef long long ll; ll read() { ll x;scanf("%lld",&x);return x; } int fa[100],d[100],sum[100]; int n; vector<int>e[100],a; int lca(int x,int y) { while(d[x]>d[y]) x=fa[x]; while(d[x]<d[y]) y=fa[y]; while(x!=y) x=fa[x],y=fa[y]; return x; } void dfs(int x) { for(auto y:e[x]) { if(y==fa[x])continue; fa[y]=x; d[y]=d[x]+1; dfs(y); } } void work(int d) { if(d==n+1) { if(a.size()==0)return ; int t=a[0]; for(auto x:a) t=lca(x,t); if(a.size()&1) sum[t]++; else sum[t]--; return ; } a.push_back(d); work(d+1); a.pop_back(); work(d+1); } int main() { n=read(); for(int i=1;i<n;i++) { int x=read(),y=read(); e[x].push_back(y); e[y].push_back(x); } dfs(1); work(1); for(int i=1;i<=n;i++) cout<<sum[i]<<' '; }
可以ac的代碼(大概:
#include <bits/stdc++.h> using namespace std; typedef long long ll; ll read() { ll x;scanf("%lld",&x);return x; } int n; ll sum[200010],ans; int main() { n=read(); for(int i=1;i<n;i++) sum[read()]--; for(int i=1;i<=n;i++) ans+=(1-sum[i])*read(); cout<<ans; }
L
二維前綴和板子題
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll read() { ll x; scanf("%lld",&x); return x; } int n,m,k,sum[4][1010][1010]; int a,b,c,d; char s[1010]; int main() { n=read();m=read();k=read(); for(int i=1;i<=n;i++) { scanf("%s",s+1); for(int j=1;j<=m;j++) { sum[1][i][j]=sum[1][i-1][j]+sum[1][i][j-1]-sum[1][i-1][j-1]+(s[j]=='C'); sum[2][i][j]=sum[2][i-1][j]+sum[2][i][j-1]-sum[2][i-1][j-1]+(s[j]=='M'); sum[3][i][j]=sum[3][i-1][j]+sum[3][i][j-1]-sum[3][i-1][j-1]+(s[j]=='F'); } } for(;k;k--) { a=read();b=read();c=read();d=read(); for(int i=1;i<=3;i++) printf("%d ",sum[i][c][d]-sum[i][c][b-1]-sum[i][a-1][d]+sum[i][a-1][b-1]); printf("\n"); } }
M
理解題意後發現只需要對每個商家的物品從大到小排序,選前第i大的物品做揹包,體積是i,假價值是(Σai)-X。f[i][j]表示前i個商家用j個物品最多賣多少錢。複雜度m*n+n*n
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll read() { ll x; scanf("%lld",&x); return x; } int n,m,k; int x[1010],f[1010][1010]; vector<int>a[1010]; int main() { n=read();m=read();k=read(); for(int i=1;i<=m;i++) x[i]=read(); for(int i=1;i<=n;i++) { int v=read(); a[read()].push_back(v); } for(int i=1;i<=k;i++) f[0][i]=-1e9; for(int i=1;i<=m;i++) { for(int kk=1;kk<=k;kk++) f[i][kk]=f[i-1][kk]; sort(a[i].begin(),a[i].end(),greater<int>()); for(int j=0,cnt=1,sum=0;j<a[i].size();j++,cnt++) { sum+=a[i][j]; for(int kk=k;kk>=cnt;kk--) f[i][kk]=max(f[i][kk],f[i-1][kk-cnt]+sum-x[i]); } } cout<<f[m][k]; }