文章目录

传送门

又一场原地爆炸的比赛。

A题

传送门 简单思维题

题意:给一个4∗44*44∗4的格子图和一个01串,你要根据01串放1∗21*21∗2的木块,如果是0就竖放一个,是1就横放一个,一行或者一列满了可以直接消掉。

现在让你每次输出放下木块的坐标,并保证所有操作中没有木块相交。


思路:

可以直接按照自己的思路模拟然后我这个sb想了好久用什么策略

下来之后突然想到一个更简单的做法,我们保证如果竖放先放(1,1)(1,1)(1,1),如果横放先放(4,4)(4,4)(4,4),这样接下来无论是横放还是竖放都会消掉之前放过的一个。

比赛代码(丑:

  1. #include<bits/stdc++.h>
  2. #define ri register int
  3. #define fi first
  4. #define se second
  5. using namespace std;
  6. inline int read(){
  7. int ans=0;
  8. char ch=getchar();
  9. while(!isdigit(ch))ch=getchar();
  10. while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
  11. return ans;
  12. }
  13. char s[1005];
  14. int n,vis[5][5];
  15. inline void update(){
  16. for(ri i=1;i<=4;++i)if(vis[i][1]&&vis[i][2]&&vis[i][3]&&vis[i][4])vis[i][1]=vis[i][2]=vis[i][3]=vis[i][4]=0;
  17. for(ri i=1;i<=4;++i)if(vis[1][i]&&vis[2][i]&&vis[3][i]&&vis[4][i])vis[1][i]=vis[2][i]=vis[3][i]=vis[4][i]=0;
  18. }
  19. inline void find(int type){
  20. if(!type){
  21. for(ri j=1;j<=4;++j)for(ri i=1;i<=3;++i){
  22. if(!vis[i][j]&&!vis[i+1][j]){
  23. vis[i][j]=vis[i+1][j]=1;
  24. cout<<i<<' '<<j<<'\n';
  25. return update();
  26. }
  27. }
  28. }
  29. else{
  30. for(ri i=1;i<=4;++i)for(ri j=1;j<=3;++j){
  31. if(!vis[i][j]&&!vis[i][j+1]){
  32. vis[i][j]=vis[i][j+1]=1;
  33. cout<<i<<' '<<j<<'\n';
  34. return update();
  35. }
  36. }
  37. }
  38. }
  39. int main(){
  40. scanf("%s",s+1),n=strlen(s+1);
  41. for(ri i=1;i<=n;++i)find(s[i]-'0');
  42. return 0;
  43. }

B题

传送门 二分答案

题意简述:你需要通过不超过60次询问来猜一个数a,a≤1e9a,a\le1e9a,a≤1e9,每次可以问两个数x,yx,yx,y,如果(xmod&ThinSpace;&ThinSpace;a)≥(ymod&ThinSpace;&ThinSpace;a)(x\mod a)\ge (y\mod a)(xmoda)≥(ymoda)会返回000否则返回111


思路:

我们考虑倍增求出aaa的范围然后再二分求aaa的准确值。

最开始先让x=0,y=1x=0,y=1x=0,y=1然后问,如果返回111就说明aaa不在区间(x,y](x,y](x,y]里,那么令x=y,y=y∗2+1x=y,y=y*2+1x=y,y=y∗2+1继续问下去知道返回000位置。

返回000时说明aaa的取值在(x,y](x,y](x,y]之间,那么我们二分aaa的值一直问x,midx,midx,mid来缩小范围即可。

代码:

  1. #include<bits/stdc++.h>
  2. #define ri register int
  3. #define fi first
  4. #define se second
  5. using namespace std;
  6. inline int read(){
  7. int ans=0;
  8. char ch=getchar();
  9. while(!isdigit(ch))ch=getchar();
  10. while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
  11. return ans;
  12. }
  13. char s[6];
  14. typedef long long ll;
  15. int main(){
  16. while(scanf("%s",s)){
  17. if(s[0]=='e')break;
  18. if(s[0]=='m')break;
  19. ll x=0,y=1;
  20. while(cout<<"? "<<x<<' '<<y<<endl,fflush(stdout),scanf("%s",s),s[0]=='y'){
  21. x=y,y=x*2+1;
  22. }
  23. if(s[0]=='e')break;
  24. ll l=x+1,r=y,ans=y;
  25. while(l<=r){
  26. ll mid=l+r>>1;
  27. bool f;
  28. cout<<"? "<<x<<' '<<mid<<endl,fflush(stdout),scanf("%s",s),f=s[0]=='x';
  29. if(s[0]=='e')break;
  30. if(f)r=mid-1,ans=mid;
  31. else l=mid+1;
  32. }
  33. cout<<"! "<<ans<<endl;
  34. fflush(stdout);
  35. }
  36. return 0;
  37. }

C题

传送门 结论+构造

题意简述:给一张无重边自环的无向图,每个点度数至少为3,现在给出kkk,要求你构造出以下两类答案中的任意一种:

  1. 找到一条路径,使得其长度≥nk\ge\frac nk≥kn​
  2. 找到kkk个环,使得每个环长度至少为333且不为333的倍数,且每个环中至少有一个点在所有输出的环中只出现过一次。

思路:

我们先dfsdfsdfs构造出图的一个生成树,这个时候如果闲的胃疼可以求一遍直径去构造第一类答案,也可以直接枚举每个点的深度来判断能不能简单构造,如果不行就直接去构造多个环的答案。

然后考虑如何构造出多个环的答案,在生成树上面每个数的深度都不能满足条件的时候说明至少有kkk个 叶子结点,由于每个点度数至少为333,因此这个叶子结点除了连接父亲的树边以外还存在跟自己祖先连接的两条非树边 注意这里说的是祖先,因为如果不是祖先的话dfs的时候会走过去,它就不是叶子节点了

然后说明至少有两个环,且这个叶子结点可以当做那个在所有环中只出现过一次的特殊点。

然后可以用如下方法构造答案。

  1. 两个环中至少有一个长度不是333的倍数,直接输出这个环。
  2. 两个环的长度都是333的倍数,那么设离当前叶子结点近的点是yyy,原的是xxx,叶子结点是zzz,我们把y−&gt;xy-&gt;xy−>x路径上所有点和zzz拿来构造成一个环,这个环的长度是3k+13k+13k+1满足题意。

代码(略丑:

  1. #include<bits/stdc++.h>
  2. #define ri register int
  3. using namespace std;
  4. inline int read(){
  5. int ans=0;
  6. char ch=getchar();
  7. while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
  8. return ans;
  9. }
  10. const int N=250005,M=5e5+5;
  11. int n,m,k,dep[N],fa[N];
  12. bool leaf[N],vis[N];
  13. vector<int>e[N];
  14. void dfs(int p){
  15. leaf[p]=vis[p]=1;
  16. for(ri i=0,v;i<e[p].size();++i){
  17. if(vis[v=e[p][i]])continue;
  18. leaf[p]=0,dep[v]=dep[p]+1,fa[v]=p,dfs(v);
  19. }
  20. }
  21. int main(){
  22. n=read(),m=read(),k=read();
  23. for(ri i=1,u,v;i<=m;++i)u=read(),v=read(),e[u].push_back(v),e[v].push_back(u);
  24. dep[1]=1,dfs(1);
  25. int tmp=(n+k-1)/k;
  26. for(ri i=1;i<=n;++i){
  27. if(dep[i]>=tmp){
  28. puts("PATH");
  29. printf("%d\n",dep[i]);
  30. while(i){
  31. printf("%d ",i);
  32. i=fa[i];
  33. }
  34. return 0;
  35. }
  36. }
  37. puts("CYCLES");
  38. vector<int>pos;
  39. for(ri i=1;i<=n&&pos.size()<k;++i)if(leaf[i])pos.push_back(i);
  40. for(ri i=1,p;i<=k;++i){
  41. bool f=0;
  42. p=pos[i-1];
  43. for(ri j=0,v;j<e[p].size();++j){
  44. if((v=e[p][j])!=fa[p]&&(dep[p]-dep[v]+1)%3){
  45. printf("%d\n",dep[p]-dep[v]+1),f=1;
  46. while(fa[p]!=fa[v]){
  47. printf("%d ",p);
  48. p=fa[p];
  49. }
  50. printf("%d",p);
  51. puts("");
  52. break;
  53. }
  54. }
  55. if(f)continue;
  56. vector<int>bad;
  57. for(ri j=0,v;j<e[p].size()&&bad.size()<2;++j)if((v=e[p][j])!=fa[p])bad.push_back(v);
  58. int x=bad[0],y=bad[1];
  59. if(dep[x]>dep[y])swap(x,y);
  60. printf("%d\n",dep[y]-dep[x]+2);
  61. printf("%d ",p);
  62. while(fa[x]!=fa[y]){
  63. printf("%d ",y);
  64. y=fa[y];
  65. }
  66. printf("%d",y);
  67. puts("");
  68. }
  69. return 0;
  70. }

D题

传送门 状压dp好题

题意简述:给nnn个二元组和一个kkk。

二元组(ai,ei)(a_i,e_i)(ai​,ei​)表示第iii个位置的权值是aia_iai​,贡献是eie_iei​。

现在对于每个位置可以让它的权值除以它自己一个不超过kkk的约数,要求从nnn个数中选择若干个数出来,使得它们的权值在除以约数过后的gcdgcdgcd为111,花费的代价是选出来的选择数的个数乘上选出来的所有数的贡献和。

数据范围:n≤1e5,k,ai≤1e12n\le1e5,k,a_i\le1e12n≤1e5,k,ai​≤1e12


思路:

考虑到gcdgcdgcd的范围也是[1,1e12][1,1e12][1,1e12],不难证明这个gcdgcdgcd最多有不超过121212个不同的质因子。

先思考一个问题:怎么去除自己的约束最优?

我们先令gcd=a1p1a2p2...akpkgcd=a_1^{p_1}a_2{p^2}...a_k^{p_k}gcd=a1p1​​a2​p2...akpk​​

显然对于一个要计入答案的数valvalval,只用关心它和gcdgcdgcd都有的质因数。

所以令val=t∗a1q1a2q2...akqkval=t*a_1^{q_1}a_2^{q_2}...a_k^{q_k}val=t∗a1q1​​a2q2​​...akqk​​,其中(t,a1)=(t,a2)=...=(t,ak)=1(t,a_1)=(t,a_2)=...=(t,a_k)=1(t,a1​)=(t,a2​)=...=(t,ak​)=1

那么对于这个数,我们选择它肯定就要它自己使得若干个幂次不为000的质数幂全部去掉,否则不如不选它,即去掉a1q1,a2q2,...,akqka_1^{q_1},a_2^{q_2},...,a_k^{q_k}a1q1​​,a2q2​​,...,akqk​​中的至少一个 这里去掉的意思指的是用除法除掉,这样之后取gcd的时候如果选这个数这个被除掉的质数幂就不会算进去

这样一来,我们选出来的每个数至少会去掉一种之前没出现过的质数幂,因此最多选择不超过12个数就能够使得它们在除去质因子之后的gcdgcdgcd为1。

于是可以设计状态fi,jf_{i,j}fi,j​表示现在已经去除的质因子的集合为iii,用了jjj个数。

考虑先把所有相同的数并在一起(因为它们分解之后也是相同的)

转移的话可以先对于每个数预处理出另外一个dpdpdp数组ggg,gig_igi​表示对于这个数要使得被除去的质数幂状态为iii所需的最小这个数的个数(因为把相同的并在一起所以每个数的个数不一定是1)。

然后再枚举子集转移就行了。

细节较多。

代码:

  1. #include<bits/stdc++.h>
  2. #define ri register int
  3. using namespace std;
  4. typedef long long ll;
  5. inline ll read(){
  6. ll ans=0;
  7. char ch=getchar();
  8. while(!isdigit(ch))ch=getchar();
  9. while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
  10. return ans;
  11. }
  12. inline map<ll,int> solve(ll x){
  13. map<ll,int>ret;
  14. ret.clear();
  15. for(ll i=2;i*i<=x;++i)while(x%i==0)x/=i,++ret[i];
  16. if(x^1)++ret[x];
  17. return ret;
  18. }
  19. const ll inf=1e18;
  20. const int N=(1<<12)+5,M=13,K=1e6+5;
  21. int n,m;
  22. ll k,a[K],b[K],gc,res=inf;
  23. int main(){
  24. n=read(),k=read(),gc=0;
  25. for(ri i=1;i<=n;++i)gc=__gcd(a[i]=read(),gc);
  26. for(ri i=1;i<=n;++i)b[i]=read();
  27. map<ll,int>fac=solve(gc);
  28. vector<ll>divv;
  29. for(map<ll,int>::iterator it=fac.begin();it!=fac.end();++it)divv.push_back(it->first);
  30. m=divv.size();
  31. vector<ll>v(m);
  32. map<vector<ll>,vector<ll> >mp;
  33. for(ri i=1;i<=n;++i){
  34. for(ri j=0;j<m;++j){
  35. v[j]=1;
  36. while(a[i]%divv[j]==0)a[i]/=divv[j],v[j]*=divv[j];
  37. }
  38. mp[v].push_back(b[i]);
  39. }
  40. vector<vector<ll> >f(1<<m,vector<ll>(m+1,inf));
  41. f[0][0]=0;
  42. for(map<vector<ll>,vector<ll> >::iterator it=mp.begin();it!=mp.end();++it){
  43. vector<ll>mul=it->first,sum=it->second,g(1<<m,inf);
  44. sort(sum.begin(),sum.end());
  45. for(ri i=1;i<sum.size();++i)sum[i]+=sum[i-1];
  46. for(ri i=0;i<(1<<m);++i){
  47. ll mult=1;
  48. for(ri j=0;j<m;++j)if((i>>j)&1)mult*=mul[j];
  49. if(mult<=k)g[i]=1;
  50. }
  51. for(ri i=0;i<(1<<m);++i)for(ri j=i;j;j=(j-1)&i){if(j==i)continue;g[i]=min(g[i],g[i^j]+g[j]);}
  52. for(ri i=(1<<m)-1;~i;--i)for(ri j=i;j;j=(j-1)&i){
  53. if(g[j]>sum.size())continue;
  54. for(ll k=0;g[j]+k<=m;++k)f[i][k+g[j]]=min(f[i][k+g[j]],f[i^j][k]+sum[g[j]-1]);
  55. }
  56. }
  57. for(ri i=0;i<=m;++i)if(f[(1<<m)-1][i]^inf)res=min(res,f[(1<<m)-1][i]*i);
  58. cout<<(res==inf?-1:res);
  59. return 0;
  60. }

Codeforces 1103 简要题解(持续更新)的更多相关文章

  1. Codeforces 863 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 简要题解?因为最后一题太毒不想写了所以其实是部分题解... A题 传送门 题意简述:给你一个数,问你能不能通过加前导000使其成为一个回文数 ...

  2. LeetCode python实现题解(持续更新)

    目录 LeetCode Python实现算法简介 0001 两数之和 0002 两数相加 0003 无重复字符的最长子串 0004 寻找两个有序数组的中位数 0005 最长回文子串 0006 Z字型变 ...

  3. Codeforces 1098 简要题解

    文章目录 前言 A题 B题 C题 D题 E题 传送门 前言 没错因为蒟蒻太菜了这场的最后一道题也咕掉了,只有AAA至EEE的题解233 A题 传送门 题意简述:给出一棵带点权的树,根节点深度为111, ...

  4. Codeforces 381 简要题解

    做的太糟糕了...第一题看成两人都取最优策略,写了个n^2的dp,还好pre-test良心(感觉TC和CF的pretest还是很靠谱的),让我反复过不去,仔细看题原来是取两边最大的啊!!!前30分钟就 ...

  5. [bzoj\lydsy\大视野在线测评]题解(持续更新)

    目录: 一.DP 二.图论 1.最短路 2.强连通分量 三.利用单调性维护 四.贪心 五.数据结构 1.并查集 六.数学 1.计数问题 2.数学分析 七.博弈 八.搜索 /////////////// ...

  6. Codeforces 873 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 传送门 A题 传送门 题意: 一个人要做nnn件事,时间花费分别为a1,a2,...,an,a1≤a2≤a3≤...≤ana_1,a_2,...,a_n, ...

  7. Codeforces 1120 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 传送门 A题 传送门 题意简述:给你一个mmm个数的数列,现在规定把一个数列的1,2,...,k1,2,...,k1,2,...,k分成第一组,把k+1, ...

  8. Codeforces 1114 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 传送门 然而这场div2div2div2没有什么难度比较大的题 A题 传送门 题意简述:三个人分别至少选x,y,zx,y,zx,y,z件物品,有三种物品数 ...

  9. Codeforces 1110 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 众所周知ldxoildxoildxoi这种菜鸡选手是不会写HHH题的,因此该篇博客只有AAA题至GGG题的题解,实在抱歉. A题 传送门 题 ...

随机推荐

  1. mybatis知识点(已掌握)

    1.${} 和 #{} 的区别? ${} 直接显示传入数据,不能防止sql注入,一般用于传数据库对象(比如表名). #{} 传入数据被当成字符串,自动加上双引号,防止sql注入. 2.有哪些Execu ...

  2. Netty实践一(数据通信)

    我们需要了解下在真正项目应用中如何去考虑Netty的使用,大体上对于一些参数设置都是根据服务器性能决定的.这个不是最主要的. 我们需要考虑的问题是两台机器(甚至多台)使用Netty的怎样进行通信,大体 ...

  3. day 25 udp, socketserver

    建立UDP连接的示例: # server端 import socket sk = socket.socket(type=socket.SOCK_DGRAM) sk.bind(('127.0.0.1', ...

  4. Android Studio 检查Top Activity

    public void CheckTop(String packagename,int casenum) { Context context = getBaseContext(); ActivityM ...

  5. selenium去掉下载弹窗

    from selenium import webdriver import time import urllib2 class Download(): def __init__(self): self ...

  6. 使用java5的注解和Sping/AspectJ的AOP 来实现Memcached的缓存

    使用java5的注解和Sping/AspectJ的AOP 来实现Memcached的缓存 今天要介绍的是Simple-Spring-Memcached,它封装了对MemCached的调用,使MemCa ...

  7. SpringMVC之controller篇1

    概述 继 Spring 2.0 对 Spring MVC 进行重大升级后,Spring 2.5 又为 Spring MVC 引入了注解驱动功能.现在你无须让 Controller 继承任何接口,无需在 ...

  8. 关于sublime Text 3安装sublimecodeIntel插件配置方法

    打开preferences-package settings-sublimecodeIntel-settings users 添加 { "JavaScript": { " ...

  9. 让键盘输入不影响界面的动态效果(C++)

    输入语句,当代码运行到它的时候就要等待输入,才能执行下一行代码,如果不输入的话,就相当于在这里暂停了(程序设计老师讲过通过这样的方式以达到暂停(pause)的效果),但如果我们想要如果没输入仍然可以运 ...

  10. Python.SQLAlchemy.0

    1. SQLAlchemy and You http://lucumr.pocoo.org/2011/7/19/sqlachemy-and-you/ 2. Overview http://docs.s ...