2017CCPC杭州题目PDF

Problem A. Super-palindrome

题解:

  给你一个字符串,每一步可以将一个字符替换为另一个字符,问你最少多少步可以使得,该字符串任意奇数子串为回文串,偶数子串为回文串。

满足上面条件一定是ababab这种形式,所以我们只要找到数量最多的两种字符用n-numa-numb得到ans1,有可能一种字符的数量过多,这时候我们只要把所有字符都变成这种字符就行了。得到n-numa,ans2;

在ans1和ans2中去最小值就是答案了;

参考代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=;
int T,a[maxn];
char s[maxn]; int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%s",s+);
int len=strlen(s+),ans=;
for(int i=;i<=len;++i) a[i]=s[i]-'a'+;
for(int i=;i<=;++i)
{
for(int j=;j<=;++j)
{
int sum=;
for(int k=;k<=len;++k)
{
if((k&)&&a[k]==i) ++sum;
if(!(k&)&&a[k]==j) ++sum;
}
ans=max(ans,sum);
}
}
for(int i=;i<=;++i)
{
int sum=;
for(int k=;k<=len;++k)
if(a[k]==i) sum++;
ans=max(ans,sum);
}
printf("%d\n",len-ans); } return ;
}

Problem B. Master of Phi

  公式化简;

参考代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod=;
int quick_pow(int a,int b){int ans=;while(b) {if(b&) ans=1LL*a*ans%mod;a=1LL*a*a%mod;b>>=;} return ans;}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int m;
scanf("%d",&m);
LL ans=;
for(int i=;i<=m;i++)
{
int p,q;
scanf("%d%d",&p,&q);
ans=1LL*ans*(quick_pow(p,q)+1LL*quick_pow(p,q-)*(p-)%mod*q%mod)%mod;
}
printf("%lld\n",ans);
}
}

Problem C. Hakase and Nano

题解:

  给你n对石头,每堆a[i]个,一个d,d==1时表示Hakase先手,d==2时表示Nano先手,每次从一堆中拿任意个石头,至少拿一个;但是这是一个不平等博弈,就是Hakase可以连续拿两次,而Nano只能连续拿一次。问你Hakase是否可以取胜。

  首先如果d==1,那么只有当所有堆石头的数量都为1且数量%3==1的时候Hakase才必败,其他情况都是必胜。

d==2的时候,因为N想赢所以肯定想转换到上述H会输的状态,所以H在n是3的倍数,且有n-1个数为1时会输(这时N只需从不是1的那堆石子里拿掉一些石子使状态变为1 1 1),或者n是3的倍数余1,且n个数为1时会输(此时N只需拿掉一堆石子,H就到了必输态),或者n是3的倍数余1,且n-1个数为1时会输(此时N只需拿掉一堆不是1的石子,H就到了必输态)。

参考代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int T,n,d,x; int main()
{
scanf("%d",&T);
while(T--)
{
int cnt=;
scanf("%d%d",&n,&d);
for(int i=;i<=n;++i) scanf("%d",&x),cnt+=(x==);
if(d==)
{
if(cnt==n&&n%==) puts("No");
else puts("Yes");
}
else
{
if(n%==&&cnt>=n-) puts("No");
else if(n%==&&cnt==n-) puts("No");
else puts("Yes");
}
} return ;
}

Problem D. Master of Random

题解:

  给你一棵树,每个节点有个权值,现在这个树是随机的,现在随即选择一颗子树,问你这棵子树的节点权值和的期望为多少;

  我们考虑对于一颗子树上面的点,他到子树的根必定在他到整个树的根的路径上面,然后,我们考虑每次添加一个节点,他要么是子树根节点,要么自己单独型号才能一个子树。

参考代码:

#include<bits/stdc++.h>
using namespace std;
#define mod 998244353
typedef long long ll;
const int maxn=1e5+;
int T,n;
ll num,sum,ans,a[maxn],f[maxn];
ll qpow(ll x,ll y)
{
ll res=;
while(y)
{
if(y&) res=res*x%mod;
x=x*x%mod;
y>>=;
}
return res;
} int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
sum=;ans=;
num=qpow(n,mod-);
for(int i=;i<=n;i++) scanf("%lld",a+i);
for(int i=;i<=n;i++)
{
f[i]=(sum*qpow(i-,mod-)%mod+)%mod;
sum=(sum+f[i])%mod;
ans=(ans+a[i]*f[i]%mod)%mod;
}
ans=(ans*num)%mod; printf("%lld\n",ans);
}
return ;
}

Problem E. Master of Subgraph

题解:

  题目给你一个树图,然后每个节点一个权值a[i],给你一个m,对于x=1~m :问你该树图里面是否有连通子图的值为x,输出x对应取值下的答案(0/1);

  我们考虑点分治,用bitset维护经过每个点的链的权值和。

参考代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=3e3+;
const int maxm=1e5+;
bitset<maxm> bit[maxn],ans;
int T,n,m,w[maxn];
vector<int> g[maxn];
int root,mx[maxn],siz[maxn],S;
bool vis[maxn]; void getroot(int u,int fa)
{
siz[u]=;mx[u]=;
for(int i=,len=g[u].size();i<len;++i)
{
int v=g[u][i];
if(v==fa || vis[v]) continue;
getroot(v,u);
siz[u]+=siz[v];
mx[u]=max(mx[u],siz[v]);
}
mx[u]=max(mx[u],S-mx[u]);
if(mx[u]<mx[root]) root=u; } void calc(int u,int fa)
{
siz[u]=;bit[u]<<=w[u];
for(int i=,len=g[u].size();i<len;++i)
{
int v=g[u][i];
if(vis[v]||v==fa) continue;
bit[v]=bit[u];
calc(v,u);
bit[u]|=bit[v];
siz[u]+=siz[v];
}
} void solve(int u)
{
vis[u]=true;
bit[u].reset();bit[u].set();
calc(u,);
ans|=bit[u];
for(int i=,len=g[u].size();i<len;++i)
{
int v=g[u][i];
if(vis[v]) continue;
root=; S=siz[v];
getroot(v,);
solve(root);
} } int main()
{
scanf("%d",&T);
while(T--)
{
ans.reset();
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i) g[i].clear(),vis[i]=;
for(int i=;i<n;++i)
{
int u,v;
scanf("%d%d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
for(int i=;i<=n;++i) scanf("%d",w+i);
S=n; root=;mx[]=INF;
getroot(,);
solve();
for(int i=;i<=m;++i)
printf("%d",(int)ans[i]);
puts(""); } return ;
}

Problem J. Master of GCD

题意:

  给出T组数据(1 <= T  <= 10),每组数据中,有两个数n(1  <= n <= 10^5)和 m (1 <= m <= 10^5)。其中 n 表示有n个由1组成的数, m表示下面给出m组数据,每组数据由 p,q,k 组成。表示区间p 到 q,增大k倍(k 等于2 或者 3).输出这n个数最终的最大公约数。由于数据比较大,因此需要mod 998244353。 
  差分一下,维护2的次幂和3的次幂;

参考代码:

#include<bits/stdc++.h>
using namespace std;
#define mod 998244353
typedef long long ll;
const int maxn=1e5+;
int T,n,m;
ll x[maxn],y[maxn];
ll qpow(ll x,ll y)
{
ll res=;
while(y)
{
if(y&) res=res*x%mod;
x=x*x%mod;
y>>=;
}
return res;
} int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i) x[i]=y[i]=;
for(int i=;i<=m;++i)
{
int l,r,xx;
scanf("%d%d%d",&l,&r,&xx);
if(xx==) x[l]++,x[r+]--;
else y[l]++,y[r+]--;
} for(int i=;i<=n;++i) x[i]+=x[i-],y[i]+=y[i-];
ll ans1=x[],ans2=y[];
for(int i=;i<=n;++i)
ans1=min(ans1,x[i]),ans2=min(ans2,y[i]);
ll ans=qpow(,ans1)*qpow(,ans2)%mod;
printf("%lld\n",ans);
} return ;
}

Problem K. Master of Sequence

题解:

参考代码:

#include<bits/stdc++.h>
#define mod 998244353
const int maxn=1e6+;
using namespace std;
typedef long long ll;
struct node{
ll a,b;
} p[maxn];
int T,n,m,num[][],cnt[];
ll s;
int main()
{
scanf("%d",&T);
while(T--)
{
s=;
memset(num,,sizeof num);
memset(cnt,,sizeof cnt);
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i) scanf("%d",&p[i].a);
for(int i=;i<=n;++i)
{
scanf("%d",&p[i].b);
s+=(p[i].b/p[i].a);
cnt[p[i].a]++;
num[p[i].a][p[i].b%p[i].a]++;
}
for(int i=;i<=;i++)
for(int j=i-;j>=;j--)
num[i][j]+=num[i][j+]; while(m--)
{
int ty,y,z;
scanf("%d",&ty);
if(ty==)
{
scanf("%d%d",&y,&z);
for(int i=p[y].b%p[y].a;i>=;--i) num[p[y].a][i]--;
s-=(p[y].b/p[y].a);
cnt[p[y].a]--;
p[y].a=z;
s+=(p[y].b/p[y].a);
cnt[z]++;
for(int i=p[y].b%z;i>=;--i) num[z][i]++;
}
else if(ty==)
{
scanf("%d%d",&y,&z);
for(int i=p[y].b%p[y].a;i>=;--i) num[p[y].a][i]--;
s-=(p[y].b/p[y].a);
p[y].b=z;
s+=(p[y].b/p[y].a);
for(int i=p[y].b%p[y].a;i>=;--i) num[p[y].a][i]++;
}
else
{
ll k;
scanf("%lld",&k);
ll l=,r=1e13,ans;
while(l<=r)
{
ll mid=l+r>>;
ll sum=-s;
for(int i=;i<=;++i) sum+=mid/i*cnt[i]-num[i][mid%i+];
if(sum>=k) r=mid-,ans=mid;
else l=mid+;
}
printf("%lld\n",ans);
}
}
} return ;
}

 

2017 CCPC杭州 题解的更多相关文章

  1. HDU 6271 Master of Connected Component(2017 CCPC 杭州 H题,树分块 + 并查集的撤销)

    题目链接  2017 CCPC Hangzhou Problem H 思路:对树进行分块.把第一棵树分成$\sqrt{n}$块,第二棵树也分成$\sqrt{n}$块.    分块的时候满足每个块是一个 ...

  2. HDU 6270 Marriage (2017 CCPC 杭州赛区 G题,生成函数 + 容斥 + 分治NTT)

    题目链接  2017 CCPC Hangzhou Problem G 题意描述很清晰. 考虑每个家庭有且仅有$k$对近亲的方案数: $C(a, k) * C(b, k) * k!$ 那么如果在第$1$ ...

  3. HDU 6268 Master of Subgraph (2017 CCPC 杭州 E题,树分治 + 树上背包)

    题目链接  2017 CCPC Hangzhou  Problem E 题意  给定一棵树,每个点有一个权值,现在我们可以选一些连通的点,并且把这点选出来的点的权值相加,得到一个和. 求$[1, m] ...

  4. 2017 CCPC 杭州 流水账

    day0: 队内训练ccpc 秦皇岛,敝校自己出的题,感觉一个星期没怎么写代码,手生得很,不出意料被打飞了. day1 (热身赛): 热身赛还算顺利,A题看有的队几分钟就草过去了,还以为又是西安ICP ...

  5. 2017 CCPC 杭州 HDU6273J 区间修改(线段树&差分数组)

    http://acm.hdu.edu.cn/downloads/CCPC2018-Hangzhou-ProblemSet.pdf 解析 线段树区间延迟更新 或 差分数组 两个数   统计2和3的最少的 ...

  6. 2017 CCPC 杭州 HDU6265B 积性函数

    题目链接 http://acm.hdu.edu.cn/downloads/CCPC2018-Hangzhou-ProblemSet.pdf B题 数论题      h(n)=∑ d|n φ(d) × ...

  7. 2017 CCPC 哈尔滨站 题解

    题目链接  2017 CCPC Harbin Problem A Problem B Problem D Problem F Problem L 考虑二分答案. 设当前待验证的答案为x 我们可以把第二 ...

  8. ccpc杭州站 赛后总结

    Ccpc杭州站赛后总结 2017年11月4号五号,我参加了ccpc杭州站的比赛,我的队友是聂少飞和王艳,在4号一点半,举行了比赛开幕式,听着教练代表的发言,听着参赛选手代表的发言,听着志愿者的发言,都 ...

  9. 2017 ccpc哈尔滨 A题 Palindrome

    2017 ccpc哈尔滨 A题 Palindrome 题意: 给一个串\(T\),计算存在多少子串S满足\(S[i]=S[2n−i]=S[2n+i−2](1≤i≤n)\) 思路: 很明显这里的回文串长 ...

随机推荐

  1. Go组件学习——Web框架Gin

    以前学Java的时候,和Spring全家桶打好关系就行了,从Spring.Spring MVC到SpringBoot,一脉相承. 对于一个Web项目,使用Spring MVC,就可以基于MVC的思想开 ...

  2. T-SQL Part XII: Access Remote SQL Server

    要链接远程的SQL Server,需要一下几个步骤(以下的步骤都是在远程系统上进行): 确认远程SQL Server所监听的端口号 官方的文档是使用SQL Server Configuration M ...

  3. 直接引用MrAdvice.dll文件不能实现AOP拦截,教你1分钟解决这个问题

    直接引用MrAdvice.dll文件不能实现AOP拦截,教你1分钟解决这个问题.近日工作中,要实现一个功能,那就是业务层方法里面实现自动缓存.编写业务的C#开发人员只关注如何将业务代码编写正确就可以了 ...

  4. thinkphp5中取消了3.2版本中的单字母函数,初用tp5可能不大适应,下边给出两者的对应参照表,以便查阅。

    3.2版本 5.0版本 C config E exception G debug L lang T 废除 I input N 废除 D model M db A controller R action ...

  5. 判断DataGridView是否选中某行

    if (this.Drawing_GridView.SelectedColumns.Count == 0)//判断是否选中某行 { }

  6. nyoj 311-完全背包 (动态规划, 完全背包)

    311-完全背包 内存限制:64MB 时间限制:4000ms Special Judge: No accepted:5 submit:7 题目描述: 直接说题意,完全背包定义有N种物品和一个容量为V的 ...

  7. Python标准类型的分类

    Python有3种不同的模型可以帮助对基本类型进行分类,这些类型更好的理解类型之间的相互关系以及他们的工作原理. 1 存储模型    能保存单个字面对象的类型,称为原子或标量存储:    能保存多个对 ...

  8. 【Linux系列】配置Centos 7的软件源(二)

    目的 本文主要介绍以下内容: 设置centos的国内软件源,默认源都是国外的下载软件超级麻烦. ssh登录 下载一个shell或者cmder ssh root@192.168.10.18 #上篇设置的 ...

  9. 来理解undefined 和 null 区别

    之前虽然也知道这两个之间的区别,但是让我描述的话,感觉上还是说的不是很清楚.今天也详细看了一次这个知识点,现在来说说这两者间的区别. null: Null类型,代表“空值”,代表一个空对象指针,使用t ...

  10. 有效的减少代码中太多的if、else?-策略模式

    写这篇文章的目的和上一篇单例模式一样,策略模式也是一种常用的设计模式,太多的if-else不仅看着不太美观而且不好维护,对于自己来说也等于复习了一遍策略模式.先说一下策略 模式的定义: 策略模式封装了 ...