- A. Superhero Transformation
- 题意:
- 元音和元音,辅音和辅音字母之间可以互相转换,问两个字符串是否想同;
- 题解:直接判断即可;
-
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1010; 4 char s[N]; 5 int n,m,vis1[N],vis2[N]; 6 int judge(char x){return x=='a'||x=='e'||x=='i'||x=='o'||x=='u';} 7 int main(){ 8 // freopen("A.in","r",stdin); 9 // freopen("A.out","w",stdout); 10 scanf("%s",s+1); 11 n=strlen(s+1); 12 for(int i=1;i<=n;++i)vis1[i]=judge(s[i]); 13 scanf("%s",s+1); 14 m=strlen(s+1); 15 for(int i=1;i<=m;++i)vis2[i]=judge(s[i]); 16 int fg=0; 17 if(n!=m){ 18 puts("No"); 19 return 0; 20 } 21 for(int i=1;i<=n;++i){ 22 if(vis1[i]^vis2[i]){fg=1;break;} 23 } 24 puts(fg?"No":"Yes"); 25 return 0; 26 }
- B. Average Superhero Gang Power
- 题意:
- 长度为$n$的数组$a$,最多执行$m$次操作,每次1.将一个数+1;2.删除一个数。其中操作2对每个数最多做$k$次
- 题解:
- 枚举2做了多少次,贪心删除最小的值,尽量将剩下的次数全部用到1;
-
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define ld double 4 #define Run(i,l,r) for(int i=l;i<=r;++i) 5 using namespace std; 6 const int N=100010; 7 int n,m,k; 8 ll sum[N],a[N]; 9 int main(){ 10 // freopen("B.in","r",stdin); 11 // freopen("B.out","w",stdout); 12 scanf("%d%d%d",&n,&k,&m); 13 for(int i=1;i<=n;++i)scanf("%d",&a[i]); 14 sort(a+1,a+n+1); 15 for(int i=1;i<=n;++i)sum[i]=sum[i-1]+a[i]; 16 ld ans=0; 17 for(int i=0;i<=min(n-1,m);++i){ 18 ans=max(ans , (ld) ( sum[n]-sum[i]+min(1ll*k*(n-i) , (ll)m-i) ) / (n-i) ); 19 } 20 printf("%.20lf ",ans); 21 return 0; 22 }
- C. Creative Snap
- 题意:
- [1,2^n]的区间,每次直接删除一个区间,如果区间没有数存在代价是$A$,否则代价是$l*B*n_{a}$,$l$为区间长度,$n_{a}$为数的个数
- 题解:
- 直接做$dp$,复杂度相当于所有点的查询线段并:$O(n logn)$
-
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define ls (k<<1) 4 #define rs (k<<1|1) 5 using namespace std; 6 const int N=100010; 7 int n,k,A,B,a[N]; 8 inline int find(int l,int r){ 9 return lower_bound(a+1,a+k+1,r+1)-lower_bound(a+1,a+k+1,l); 10 } 11 ll dfs(int l,int r){ 12 int t=find(l,r); 13 if(!t)return A; 14 if(l==r)return !t?A:(ll)t*B; 15 int mid=(l+r)>>1; 16 return min(1ll*t*B*(r-l+1),dfs(l,mid)+dfs(mid+1,r)); 17 } 18 int main(){ 19 // #ifndef ONLINE_JUDGE 20 // freopen("C.in","r",stdin); 21 // freopen("C.out","w",stdout); 22 // #endif 23 scanf("%d%d%d%d",&n,&k,&A,&B); 24 for(int i=1;i<=k;++i)scanf("%d",&a[i]); 25 sort(a+1,a+k+1); 26 printf("%I64d ",dfs(1,1<<n)); 27 return 0; 28 }
- D. Destroy the Colony
- 题意:
- 给定一个由大小写字符组成的长度为偶数的字符串,好的串定义为想同字符都出现在想同的半边,询问给出两个位置$x,y$约定$x$和$y$的字符也必须在同一边问方案数;
- 题解:
- 统计每个字符的个数做背包,乘以一个可重元素的排列数就是答案,每次询问的话删除物品再加入即可;
-
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define mod 1000000007 4 #define rg register 5 #define il inline 6 using namespace std; 7 const int N=100010; 8 char s[N]; 9 int n,q,vis[200],fac[N],tot,v[N],f[N],g[N],ans[200][200],iv; 10 char gc(){ 11 static char*p1,*p2,s[1000000]; 12 if(p1==p2)p2=(p1=s)+fread(s,1,1000000,stdin); 13 return(p1==p2)?EOF:*p1++; 14 } 15 int rd(){ 16 char c=gc();int x=0; 17 while(!isdigit(c))c=gc(); 18 while(isdigit(c))x=x*10+c-'0',c=gc(); 19 return x; 20 } 21 char gt(){ 22 char c=gc(); 23 while(!isalpha(c))c=gc(); 24 return c; 25 } 26 int inv(int x){ 27 int re=1; 28 for(int y=mod-2;y;y>>=1,x=(ll)x*x%mod){ 29 if(y&1)re=(ll)re*x%mod; 30 } 31 return re; 32 } 33 int solve(int x,int y){ 34 if(!vis[x]||!vis[y])return 0; 35 for(rg int i=0;i<=n>>1;++i)g[i]=f[i]; 36 if(x!=y){ 37 int v1=vis[x]; 38 for(rg int i=0;i+v1<=n>>1;++i)f[i+v1]=(f[i+v1]-f[i]+mod)%mod; 39 v1=vis[y]; 40 for(rg int i=0;i+v1<=n>>1;++i)f[i+v1]=(f[i+v1]-f[i]+mod)%mod; 41 v1=vis[x]+vis[y]; 42 for(rg int i=(n>>1)-v1;i>=0;--i)f[i+v1]=(f[i+v1]+f[i])%mod; 43 } 44 int re = 1ll * iv * f[n>>1] %mod; 45 for(int i=0;i<=n>>1;++i)f[i]=g[i]; 46 return re; 47 } 48 int main(){ 49 // freopen("D.in","r",stdin); 50 // freopen("D.out","w",stdout); 51 scanf("%s",s+1);n=strlen(s+1); 52 for(rg int i=1;i<=n;++i)vis[s[i]]++; 53 for(rg int i=fac[0]=1;i<=n;++i)fac[i]=(ll)fac[i-1]*i%mod; 54 iv = 1ll * fac[n>>1] * fac[n>>1] %mod; 55 for(rg int i='A';i<='z';++i)if(vis[i])v[++tot]=vis[i],iv=1ll*iv*inv(fac[v[tot]])%mod; 56 f[0]=1; 57 for(rg int i=1;i<=tot;++i) 58 for(rg int j=(n>>1)-v[i];j>=0;--j){ 59 f[j+v[i]] = (f[j+v[i]]+f[j])%mod; 60 } 61 for(rg int x='A';x<='z';++x) 62 for(rg int y=x;y<='z';++y) 63 ans[x][y] = solve(x,y); 64 scanf("%d",&q); 65 for(rg int i=1,x,y;i<=q;++i){ 66 scanf("%d%d",&x,&y); 67 if(s[x]>s[y])swap(x,y); 68 printf("%d ",ans[s[x]][s[y]]); 69 } 70 /* 71 { 72 for(rg int i=0;i<=n>>1;++i)printf("%d ",f[i]); 73 }*/ 74 return 0; 75 }
- E. Tree
- 题意:
- 给定一棵树,$q$次询问,每次$k$个询问点$a_{i}$,分成至多$m$组,同组之间以$r$为根不存在祖先关系,问方案数;$n le 1e5 , sum k le 1e5$
- 题解:
- 按深度排序之后假设$h[i]$为i的祖先个数,f[i][j]表示前$i$个点分成$j$组的方案;
- $$f[i][j] = f[i-1][j] * (j-h[i]) + f[i-1][j-1] $$
- 其实不一定要深度,只需要按照$h[]$排序即可;
- $h$可以在$dfs$序上维护一下;
-
1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const int N=100010,mod=1000000007; 5 int n,q,k,m,r,a[N],fa[N][17],dep[N],hd[N],o=1,bin[20],h[N],f[N][310],st[N],ed[N],c[N],vis[N],idx; 6 struct Edge{int v,nt;}E[N<<1]; 7 char gc(){ 8 static char*p1,*p2,s[1000000]; 9 if(p1==p2)p2=(p1=s)+fread(s,1,1000000,stdin); 10 return(p1==p2)?EOF:*p1++; 11 } 12 int rd(){ 13 int x=0;char c=gc(); 14 while(c<'0'||c>'9')c=gc(); 15 while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0',c=gc(); 16 return x; 17 } 18 void adde(int u,int v){ 19 E[o]=(Edge){v,hd[u]};hd[u]=o++; 20 E[o]=(Edge){u,hd[v]};hd[v]=o++; 21 } 22 void dfs(int u,int F){ 23 st[u]=++idx; 24 fa[u][0]=F; 25 dep[u]=dep[F]+1; 26 for(int i=1;bin[i]<dep[u];++i)fa[u][i]=fa[fa[u][i-1]][i-1]; 27 for(int i=hd[u];i;i=E[i].nt){ 28 int v=E[i].v; 29 if(v==F)continue; 30 dfs(v,u); 31 } 32 ed[u]=idx; 33 } 34 int lca(int u,int v){ 35 if(dep[u]<dep[v])swap(u,v); 36 for(int i=0;i<17;++i)if(bin[i]&(dep[u]-dep[v]))u=fa[u][i]; 37 if(u==v)return u; 38 for(int i=16;~i;--i)if(fa[u][i]!=fa[v][i])u=fa[u][i],v=fa[v][i]; 39 return fa[u][0]; 40 } 41 void add(int x,int y){for(;x<=n;x+=x&-x)c[x]+=y;} 42 int ask(int x){int re=0;for(;x;x-=x&-x)re+=c[x];return re;} 43 void update(int u,int x){ 44 vis[u]+=x; 45 add(st[u],x); 46 add(ed[u]+1,-x); 47 } 48 int query(int u){ 49 int t=lca(u,r); 50 return ask(st[u])+ask(st[r])-ask(st[t])*2+vis[t]; 51 } 52 int main(){ 53 #ifndef ONLINE_JUDGE 54 freopen("E.in","r",stdin); 55 freopen("E.out","w",stdout); 56 #endif 57 n=rd();q=rd(); 58 for(int i=bin[0]=1;i<=17;++i)bin[i]=bin[i-1]<<1; 59 for(int i=1;i<n;++i)adde(rd(),rd()); 60 dfs(1,0); 61 f[0][0]=1; 62 for(int i=1;i<=q;++i){ 63 k=rd();m=rd();r=rd(); 64 for(int j=1;j<=k;++j)a[j]=rd(),update(a[j],1); 65 for(int j=1;j<=k;++j)h[j]=query(a[j])-1; 66 sort(h+1,h+k+1); 67 for(int j=1;j<=k;++j) 68 for(int l=1;l<=m;++l){ 69 f[j][l] = ((ll)f[j-1][l]*max(0,l-h[j])%mod+f[j-1][l-1])%mod; 70 } 71 int ans=0; 72 for(int l=0;l<=m;++l)ans=(ans+f[k][l])%mod; 73 printf("%d ",ans); 74 for(int j=1;j<=k;++j)update(a[j],-1); 75 } 76 return 0; 77 }