codeforces contest 1111

  • 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\n",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\n",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\n",ans[s[x]][s[y]]);
    69     }
    70     /*
    71     {
    72         for(rg int i=0;i<=n>>1;++i)printf("%d\n",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\n",ans);
    74         for(int j=1;j<=k;++j)update(a[j],-1);
    75     }
    76     return 0;
    77 }

原文地址:https://www.cnblogs.com/Paul-Guderian/p/10354426.html

时间: 2024-11-02 09:34:27

codeforces contest 1111的相关文章

Codeforces round 1111

CF Div 2 537 比赛链接 感觉题目难度OK,五个题都能做,后俩题考察人的翻译水平... 另外,$Claris$太强了... A 直接按照题意模拟,不知道为啥有人会被× 代码: #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <cstdlib> #include <queue> #include <io

CodeForces Contest #1114: Round #538 (Div. 2)

比赛传送门:CF #1114. 比赛记录:点我. 又 FST 了. [A]Got Any Grapes? 题意简述: 有三个人,第一个人需要吃绿色葡萄至少 \(a\) 个,第二个人需要吃绿色和紫色葡萄至少 \(b\) 个,第三个人需要吃绿色.紫色和黑色葡萄至少 \(c\) 个. 有 \(x\) 个绿色葡萄,\(y\) 个紫色葡萄,\(z\) 个黑色葡萄,问是否能够满足三个人的要求. 题解: #include <cstdio> int main() { int x, y, z, a, b, c;

codeforces/contest/1228

B. Filling the Grid 分行和列进行染色,扫完图以后没有被染色的格子数,就是对答案产生的贡献值,wa了一发,因为没看清样例,会有冲突情况产生,这种情况下的答案是0 #include<bits/stdc++.h> const double pi=3.14159; typedef long long int ll; const int mod=1e9+7; int amap[1010][1010]; int hh[1010],ww[1010]; ll qpow(ll a,ll b)

2019 HDOJ Multi-University Training Contest Stage 8(杭电多校)

中规中矩的一场. 题目链接:http://acm.hdu.edu.cn/contests/contest_show.php?cid=855 C: 定义函数f(d,k)为数字d在数字k中出现的次数.给定d和x,找到尽量大的k使得k<=x且f(d,k)==k. 很诡异的一题,最好的做法仍然是打表找规律.题解给了一个很神奇的结论:满足条件的k<1011且k的分布非常稀疏. 1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* defin

2019 HDOJ Multi-University Training Contest Stage 10(杭电多校)

最后一场多校打得一般般. 题目链接:http://acm.hdu.edu.cn/contests/contest_show.php?cid=857 C: E: I: BFS水题. 1 /* Codeforces Contest 2019_mutc_10 2 * Problem I 3 * Au: SJoshua 4 */ 5 #include <queue> 6 #include <cstdio> 7 #include <vector> 8 #include <s

动态开点线段树

用途 需要建立多棵独立的线段树 线段树维护的值域较大(1e9),但是操作次数较少(1e5) 特征 类似主席树的原理,动态分配每个树节点的位置(lson[],rson[]),每次只更新一条链,但是主席树是建立一颗新的树,动态开点线段树是在一棵树上不断添加节点(还是一棵树) 类似线段树的原理,push_down区间修改,push_up区间查询 例题 1.维护值域较大,线段树区间修改 cf915e https://codeforces.com/contest/915/problem/E 题意: q(3

第三届H-star 程序设计竞赛初赛题解

1.剪纸片:这是一道简单的题目,假如你身边有一张纸,一把剪刀,在H-star的比赛现场,你会这么做:(1). 将这张纸剪成两片(平行于短边剪开):(2)将其中一片剪成一个圆,作为圆柱的底面:(3) 纸的另一片的一边沿着圆的周长将圆围起来,直到围成一圈,形成一个无盖的圆柱体.需要注意的是,纸片可能会有重叠部分.聪明的你机智的你喜欢思考的你这时候就开始想,一张纸片按上述方式所组成的圆柱的最大体积是多少呢?请你用编程解决这个问题. 输入 输入第一行包含一个数字t代表接下来有t组数据: 接下来的t行,输

物联网学生科协第三届H-star现场编程比赛

问题 A: 剪纸片 时间限制: 1 Sec 内存限制: 128 MB 题目描述 这是一道简单的题目,假如你身边有一张纸,一把剪刀,在H-star的比赛现场,你会这么做: 1. 将这张纸剪成两片(平行于短边剪开): 2. 将其中一片剪成一个圆,作为圆柱的底面: 3. 纸的另一片的一边沿着圆的周长将圆围起来,直到围成一圈,形成一个无盖的圆柱体.需要注意的是,纸片可能会有重叠部分. 聪明的你机智的你喜欢思考的你这时候就开始想,一张纸片按上述方式所组成的圆柱的最大体积是多少呢?请你用编程解决这个问题.

http://codeforces.com/contest/575/problem/B

题目链接: http://codeforces.com/contest/575/problem/B 题解: 代码: #include<cstdio> #include<vector> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn = 1e5 + 10; const int DEG = 22; const in