20190922CSP-S模拟
作者:互联网
这个是USACO 2019 JAN Gold的原题,可能因为过于水,所以我即使八点多才开始做也提前ak来写一篇题解。。
A.Cow Poetry
显然押同一韵的行只需要最后一个词属于一个韵部,前面长度$K-s_i$随便排,DP一下长度$i$的有多少种,类似于背包转移,只是把物品放在内层,容量放在外层枚举,这样保证顺序不同时有不同的种类数。
然后对于每一种要求韵相同的行,可以枚举每一种韵,结合乘法原理和加法原理得出方案数。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define dbg(x) cerr << #x << " = " << x <<endl 7 using namespace std; 8 typedef long long ll; 9 typedef double db; 10 typedef pair<int,int> pii; 11 template<typename T>inline T _min(T A,T B){return A<B?A:B;} 12 template<typename T>inline T _max(T A,T B){return A>B?A:B;} 13 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;} 14 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;} 15 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;} 16 template<typename T>inline T read(T&x){ 17 x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1; 18 while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x; 19 } 20 const int N=5000+7,P=1e9+7; 21 char opt[3]; 22 int f[N],now; 23 int cnt[27],typ[N]; 24 int s[N],c[N]; 25 int n,m,k,maxc,ans=1; 26 inline void add(int&A,int B){A+=B;A>=P&&(A-=P);} 27 inline int fpow(int x,int p){int ret=1;for(;p;p>>=1,x=x*1ll*x%P)if(p&1)ret=ret*1ll*x%P;return ret;} 28 29 int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout); 30 read(n),read(m),read(k); 31 for(register int i=1;i<=n;++i)read(s[i]),MAX(maxc,read(c[i])); 32 for(register int i=1;i<=m;++i)scanf("%s",opt),++cnt[opt[0]-'A']; 33 f[0]=1; 34 for(register int i=0;i<=k;++i) 35 for(register int j=1;j<=n;++j)if(i+s[j]<=k)add(f[i+s[j]],f[i]); 36 for(register int i=1;i<=n;++i)if(k>=s[i])add(typ[c[i]],f[k-s[i]]); 37 for(register int i=0;i<26;++i)if(cnt[i]){ 38 int tmp=0; 39 for(register int j=1;j<=maxc;++j)if(typ[j]){ 40 add(tmp,fpow(typ[j],cnt[i])); 41 } 42 ans=ans*1ll*tmp%P; 43 } 44 printf("%d\n",ans); 45 return 0; 46 }View Code
B. Sleepy Cow Sorting
这个真的水。。可以发现显然最后最长的有序上升序列不要动,把前面的数不断往后插,这样就保证了次数最少。于是BIT维护一发即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define dbg(x) cerr << #x << " = " << x <<endl 7 using namespace std; 8 typedef long long ll; 9 typedef double db; 10 typedef pair<int,int> pii; 11 template<typename T>inline T _min(T A,T B){return A<B?A:B;} 12 template<typename T>inline T _max(T A,T B){return A>B?A:B;} 13 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;} 14 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;} 15 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;} 16 template<typename T>inline T read(T&x){ 17 x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1; 18 while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x; 19 } 20 const int N=1e5+7; 21 int C[N]; 22 int a[N]; 23 int n,las,pos; 24 #define lowbit(x) x&(-x) 25 inline void add(int x){for(;x<=n;x+=lowbit(x))++C[x];} 26 inline int sum(int x){int ret=0;for(;x;x-=lowbit(x))ret+=C[x];return ret;} 27 28 int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout); 29 read(n); 30 for(register int i=1;i<=n;++i)read(a[i]); 31 las=a[n];add(las);pos=n-1; 32 for(register int i=n-1;i;--i)if(MIN(las,a[i]))--pos,add(a[i]);else break; 33 printf("%d\n",pos); 34 for(register int i=1;i<=pos;++i)printf("%d ",pos-i+sum(a[i])),add(a[i]); 35 puts("");return 0; 36 }View Code
C. Shortcut
每个点到根的最短路路径是唯一的(因为字典序已经要求最小的),所以构成的最短路树就是唯一的,于是跑一遍dijkstra记录父边(注意更新min)之后在最短路树上暴力枚举把哪个和根相连,计算贡献取max即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 #define dbg(x) cerr << #x << " = " << x <<endl 8 using namespace std; 9 typedef long long ll; 10 typedef double db; 11 typedef pair<int,int> pii; 12 template<typename T>inline T _min(T A,T B){return A<B?A:B;} 13 template<typename T>inline T _max(T A,T B){return A>B?A:B;} 14 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;} 15 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;} 16 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;} 17 template<typename T>inline T read(T&x){ 18 x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1; 19 while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x; 20 } 21 const int N=1e5+7; 22 struct thxorz{int to,nxt,w;}G[N]; 23 int Head[N],tot,c[N]; 24 int n,m,t; 25 inline void Addedge(int x,int y,int z){ 26 G[++tot].to=y,G[tot].nxt=Head[x],Head[x]=tot,G[tot].w=z; 27 G[++tot].to=x,G[tot].nxt=Head[y],Head[y]=tot,G[tot].w=z; 28 } 29 int dis[N],fa[N],val[N]; 30 priority_queue<pii,vector<pii>,greater<pii> > q; 31 #define y G[j].to 32 inline void dij(){ 33 memset(fa,0x3f,sizeof fa); 34 memset(dis,0x3f,sizeof dis);q.push(make_pair(dis[1]=0,1)); 35 while(!q.empty()){ 36 int d=q.top().first,x=q.top().second;q.pop(); 37 if(dis[x]^d)continue; 38 for(register int j=Head[x];j;j=G[j].nxt) 39 if(d+G[j].w==dis[y]&&MIN(fa[y],x))val[y]=G[j].w; 40 else if(d+G[j].w<dis[y])q.push(make_pair(dis[y]=d+G[j].w,y)),fa[y]=x,val[y]=G[j].w; 41 } 42 } 43 ll ans=0; 44 int dfs(int x,int fa,int dep){ 45 int siz=c[x]; 46 for(register int j=Head[x];j;j=G[j].nxt)if(y^fa)siz+=dfs(y,x,dep+G[j].w); 47 MAX(ans,(dep-t)*1ll*siz); 48 return siz; 49 } 50 #undef y 51 int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout); 52 read(n),read(m),read(t); 53 for(register int i=1;i<=n;++i)read(c[i]); 54 for(register int i=1,x,y,z;i<=m;++i)read(x),read(y),read(z),Addedge(x,y,z); 55 dij();memset(Head,0,sizeof Head);tot=0; 56 for(register int i=2;i<=n;++i)Addedge(i,fa[i],val[i]); 57 dfs(1,0,0); 58 printf("%lld\n",ans); 59 return 0; 60 }View Code
标签:templateinline,return,int,tot,char,20190922CSP,include,模拟 来源: https://www.cnblogs.com/saigyouji-yuyuko/p/11566642.html