CodeCraft-19 and Codeforces Round #537 (Div. 2) Editorial
A
不说了
- 代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
char s1[N],s2[N];
int main()
{
scanf("%s",s1+1);
scanf("%s",s2+1);
int len=strlen(s1+1);
int len2=strlen(s2+1);
if(len!=len2){printf("No\n");return 0;}
for(int i=1;i<=min(len,len2);i++){
int tmp1=0,tmp0=0;
if(s1[i]=='a'||s1[i]=='e'||s1[i]=='i'||s1[i]=='u'||s1[i]=='o'){
tmp1=1;
}
if(s2[i]=='a'||s2[i]=='e'||s2[i]=='i'||s2[i]=='u'||s2[i]=='o'){
tmp0=1;
}
if(tmp0!=tmp1){
printf("No\n");
return 0;
}
}
printf("Yes\n");
}
B
考场爆int爽了。不说了。
- 代码
#include<bits/stdc++.h>
using namespace std;
typedef long double db;
typedef long long ll;
db ans;
const int N=1e6+5;
int n,m,k;
ll c[N];
int main()
{
cin>>n>>k>>m;
for(int i=1;i<=n;i++){
cin>>c[i];
}sort(c+1,c+n+1);
for(int i=n-1;i;i--){
c[i]+=c[i+1];
}
for(int i=1;i<=n;i++){
//cout<<c[i]<<endl;
db tot=n-i+1;
if(i-1>m)break;
db rst=1.00/tot*(db)(min((ll)k*(n-i+1),(ll)(m-i+1)));
ans=max(ans,(db)c[i]/tot+rst);
//cout<<ans<<endl;
}
printf("%.10Lf\n",ans);
}
C
动态开点之后树形dp。没了
- 代码
#include<bits/stdc++.h>
using namespace std;
int n,k;
typedef long long ll;
const int N=32*100000+5;
ll A,B;
ll t[N];int lch[N],rch[N];
int rt,cnt;
inline void add(int &x,ll l,ll r,ll pos){
if(!x)x=++cnt;
t[x]++;
if(l==r)return;
int mid=(l+r)>>1;
if(pos>mid)add(rch[x],mid+1,r,pos);
else add(lch[x],l,mid,pos);
}
ll f[N];
void dfs(int x,int l,int r){
if(x==0)return;
if(l==r){
if(t[x]==0)f[x]=A;
if(t[x]>0)f[x]=(ll)t[x]*(r-l+1)*B;return;
}
int mid=(l+r)>>1;
dfs(lch[x],l,mid);dfs(rch[x],mid+1,r);
f[x]=f[lch[x]]+f[rch[x]];
if(t[x]>0)f[x]=min(f[x],B*(ll)(r-l+1)*t[x]);
else if(t[x]==0)f[x]=min(f[x],A);
}
int main()
{
cin>>n>>k>>A>>B;
f[0]=A;
for(int i=1;i<=k;i++){
int p;cin>>p;
add(rt,1,1<<n,p);
}
dfs(rt,1,1<<n);
cout<<f[rt]<<endl;
}
D
考场读错题导致自闭。
确定了哪个在哪边之后计数随便搞,然后你直接枚举字符然后背包除回来就行了
- 代码(粘的)
#include<bits/stdc++.h>
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define ll long long
using namespace std;
const int N=1e5+100,mod=1e9+7;
int n,q,cnt[55],dp[N],f[N],fac[N],inv[N],res[55][55]; char s[N];
int id(char c){
return 'A'<=c&&c<='Z'?c-'A':c-'a'+26;
}
int ksm(int x,int y){
int s=1;
for (;y;y>>=1,x=(ll)x*x%mod) if (y&1) s=(ll)s*x%mod;
return s;
}
void init(int n){
fac[0]=1;
rep (i,1,n) fac[i]=(ll)fac[i-1]*i%mod;
inv[n]=ksm(fac[n],mod-2);
for (int i=n-1;~i;i--) inv[i]=(ll)inv[i+1]*(i+1)%mod;
}
int main(){
scanf("%s%d",s+1,&q); n=strlen(s+1); init(n);
rep (i,1,n) cnt[id(s[i])]++;
dp[0]=1;
rep (i,0,51) if (cnt[i])
for (int j=n/2;j>=cnt[i];j--) dp[j]=(dp[j]+dp[j-cnt[i]])%mod;
int v=(ll)fac[n/2]*fac[n/2]%mod;
rep (i,0,51) v=(ll)v*inv[cnt[i]]%mod;
rep (x,0,51) rep (y,0,51){
rep (i,0,n/2) f[i]=dp[i];
rep (i,cnt[x],n/2) f[i]=(f[i]+mod-f[i-cnt[x]])%mod;
if (x!=y)
rep (i,cnt[y],n/2) f[i]=(f[i]+mod-f[i-cnt[y]])%mod;
res[x][y]=(ll)f[n/2]*v%mod*2%mod;
}
while (q--){
int x,y; scanf("%d%d",&x,&y);
printf("%d\n",res[id(s[x])][id(s[y])]);
}
return 0;
}
E
一眼虚树是什么鬼?
dp的话是按照到rt的关键点个个数(记为H)排序来更新,复杂度k*m
然后你可以直接跑一个lca然后跑一个dep求出H或者你可以直接建虚树(比较懒就粘的建虚树的板子)
- 代码(因为直接粘的某道题的所以可能有些地方比较鬼畜)
/* based on bzoj 2286 */
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
typedef long long ll;
int anc[N][22];
ll mn[N];
const ll INF=1000000000000000000;
int n,m,num,dfn[N],dep[N],point[N];
bool cmp(const int a,const int b) {return dfn[a]<dfn[b];}
namespace Tr_all {
int hed[N],to[N];ll val[N];int cnt,nxt[N];
inline void adde(int u,int v,ll w) {
++cnt;
val[cnt]=w,to[cnt]=v,nxt[cnt]=hed[u];
hed[u]=cnt;
}
inline void dfs(int x,int pre) {
dfn[x]=++num;
dep[x]=dep[pre]+1;
if(x==1)mn[x]=INF;
anc[x][0]=pre;
for(int i=1; 1<<i<=n; i++) {
anc[x][i]=anc[anc[x][i-1]][i-1];
}
for(int i=hed[x]; i; i=nxt[i]) {
int v=to[i];
if(v==pre)continue;
mn[v]=min(mn[x],(ll)val[i]);
dfs(v,x);
}
}
int LCA(int x,int y) {
if(dep[x]<dep[y])swap(x,y);
for(int i=19; ~i; i--)if(dep[anc[x][i]]>=dep[y])x=anc[x][i];
if(x==y)return x;
for(int i=19; ~i; i--)if(anc[x][i]!=anc[y][i])x=anc[x][i],y=anc[y][i];
return anc[x][0];
}
}
using Tr_all::LCA;
int MX,rt;
bool ch[N];int nowid;
ll dp[N];bool flg=0;
namespace Tr_cur {
int hed[N],to[N],nxt[N],cnt;
int H[N];
inline void adde(int u,int v) {
//cout<<u<<" "<<v<<endl;
if(u==v)return;
++cnt;to[cnt]=v,nxt[cnt]=hed[u];hed[u]=cnt;
++cnt;to[cnt]=u,nxt[cnt]=hed[v];hed[v]=cnt;
}
inline void clear() {cnt=0;}
inline void DP(int x,int pre) {
H[x]=H[pre];
if(ch[x]){
ch[x]=0;if(H[x]>MX){flg=1;}
for(int i=MX;i;i--){
dp[i]=dp[i]*max(0ll,(ll)(i-H[x]))%1000000007ll+dp[i-1];
dp[i]%=1000000007ll;
}
dp[0]=0;
H[x]++;
}
for(int i=hed[x]; i; i=nxt[i]) {
int v=to[i];if(v==pre||v==x)continue;
DP(v,x);
}
hed[x]=0;ch[x]=0;
/* Myclear */
}
}
using Tr_cur::DP;
int stk[N],top;
int main()
{
scanf("%d",&n);
scanf("%d",&m);
for(int i=1; i<n; i++) {
int u,v;
scanf("%d%d",&u,&v);
Tr_all::adde(u,v,1);Tr_all::adde(v,u,1);
}
Tr_all::dfs(1,0);
while(m--) {
int tot;
scanf("%d",&tot);scanf("%d%d",&MX,&rt);
for(int i=1; i<=tot; i++){ scanf("%d",&point[i]); ch[point[i]]=1;}
point[++tot]=rt;
sort(point+1,point+tot+1,cmp);
stk[(top=1)]=1;
/*insert*/
for(int i=1; i<=tot; i++) {
int u=point[i];
int lca=LCA(u,stk[top]);
if(top==1) {stk[++top]=u;continue;}
if(lca==stk[top]){stk[++top]=u;continue;}
while(top>1&&dep[stk[top-1]]>dep[lca]) {
Tr_cur::adde(stk[top-1],stk[top]);
--top;
}
if(dep[stk[top]]>dep[lca]) {
Tr_cur::adde(lca,stk[top]);
top--;
}
if(dep[stk[top]]<dep[lca]) stk[++top]=lca;
stk[++top]=u;
}
while(--top) Tr_cur::adde(stk[top],stk[top+1]);
/**/
Tr_cur::H[rt]=0;flg=0;
for(int i=0;i<=MX;i++){dp[i]=0;}
dp[0]=1;
DP(rt,0);
ll ans=0;
for(int i=1;i<=MX;i++){ans+=dp[i];ans%=1000000007;}
printf("%lld\n",ans);
Tr_cur::clear();
}
}
没了