2017 CCPC杭州 题解
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杭州 题解的更多相关文章
- HDU 6271 Master of Connected Component(2017 CCPC 杭州 H题,树分块 + 并查集的撤销)
题目链接 2017 CCPC Hangzhou Problem H 思路:对树进行分块.把第一棵树分成$\sqrt{n}$块,第二棵树也分成$\sqrt{n}$块. 分块的时候满足每个块是一个 ...
- HDU 6270 Marriage (2017 CCPC 杭州赛区 G题,生成函数 + 容斥 + 分治NTT)
题目链接 2017 CCPC Hangzhou Problem G 题意描述很清晰. 考虑每个家庭有且仅有$k$对近亲的方案数: $C(a, k) * C(b, k) * k!$ 那么如果在第$1$ ...
- HDU 6268 Master of Subgraph (2017 CCPC 杭州 E题,树分治 + 树上背包)
题目链接 2017 CCPC Hangzhou Problem E 题意 给定一棵树,每个点有一个权值,现在我们可以选一些连通的点,并且把这点选出来的点的权值相加,得到一个和. 求$[1, m] ...
- 2017 CCPC 杭州 流水账
day0: 队内训练ccpc 秦皇岛,敝校自己出的题,感觉一个星期没怎么写代码,手生得很,不出意料被打飞了. day1 (热身赛): 热身赛还算顺利,A题看有的队几分钟就草过去了,还以为又是西安ICP ...
- 2017 CCPC 杭州 HDU6273J 区间修改(线段树&差分数组)
http://acm.hdu.edu.cn/downloads/CCPC2018-Hangzhou-ProblemSet.pdf 解析 线段树区间延迟更新 或 差分数组 两个数 统计2和3的最少的 ...
- 2017 CCPC 杭州 HDU6265B 积性函数
题目链接 http://acm.hdu.edu.cn/downloads/CCPC2018-Hangzhou-ProblemSet.pdf B题 数论题 h(n)=∑ d|n φ(d) × ...
- 2017 CCPC 哈尔滨站 题解
题目链接 2017 CCPC Harbin Problem A Problem B Problem D Problem F Problem L 考虑二分答案. 设当前待验证的答案为x 我们可以把第二 ...
- ccpc杭州站 赛后总结
Ccpc杭州站赛后总结 2017年11月4号五号,我参加了ccpc杭州站的比赛,我的队友是聂少飞和王艳,在4号一点半,举行了比赛开幕式,听着教练代表的发言,听着参赛选手代表的发言,听着志愿者的发言,都 ...
- 2017 ccpc哈尔滨 A题 Palindrome
2017 ccpc哈尔滨 A题 Palindrome 题意: 给一个串\(T\),计算存在多少子串S满足\(S[i]=S[2n−i]=S[2n+i−2](1≤i≤n)\) 思路: 很明显这里的回文串长 ...
随机推荐
- git回退之git reset
参考 https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E9%87%8D%E7%BD%AE%E6%8F%AD%E5%AF%86 https: ...
- js调用浏览器“打印”与“打印预览”
用到html <object>标签,具体做法如下: 1.在html文档任意位置添加<object>标签: <div style="border: 1px sol ...
- vue 封装方法
个我这个是局部引入方法,下次有需要全局在补上(全局:在main.js文件引入封装的方法js文件,然后用Vue.prototype) 一.新建一个js文件loading.js 二.编辑loading.j ...
- MySQL开发规范与使用技巧总结
命名规范 1.库名.表名.字段名必须使用小写字母,并采用下划线分割. a)MySQL有配置参数lower_case_table_names,不可动态更改,Linux系统默认为 0,即库表名以实际情况存 ...
- 深入理解Kafka必知必会(2)
Kafka目前有哪些内部topic,它们都有什么特征?各自的作用又是什么? __consumer_offsets:作用是保存 Kafka 消费者的位移信息 __transaction_state:用来 ...
- Json模块和Pickle模块的使用
在对数据进行序列化和反序列化是常见的数据操作,Python提供了两个模块方便开发者实现数据的序列化操作,即 json 模块和 pickle 模块.这两个模块主要区别如下: json 是一个文本序列化格 ...
- 为React绑定事件,并修改state中的值
import React from 'react' export default class ClickS extends React.Component { constructor () { sup ...
- python进程概要
进程 狭义:正在运行的程序实例. 广义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动,他是操作系统动态执行的基本单元. python的进程都是并行的. 并行:两个进程同时执行一起走. ...
- 玩转网络(一)用TTL(Time To Live)排查网络问题
先大概介绍一下TTL(Time To Live)吧! TTL翻译过来就是网络生存时间,说的是一个网络数据包,它在网络设备中转发的跳数(网络设备这里一般指的是路由器),默认值为64,也有很多设置为了12 ...
- 【集合系列】- 深入浅出的分析 Hashtable
一.摘要 在集合系列的第一章,咱们了解到,Map 的实现类有 HashMap.LinkedHashMap.TreeMap.IdentityHashMap.WeakHashMap.Hashtable.P ...