热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【CodeforcesRound#430(Div.2)ACD三个题】

·不论难度,A,C,D自己都有收获![A.KirillAndTheGame]·全是英文题,述大意:给出两组区间端点:l,r,x,y和一个k。(都是正整数,保证

·不论难度,A,C,D自己都有收获!

 

[A. Kirill And The Game]

·全是英文题,述大意:

   给出两组区间端点:l,r,x,y和一个k。(都是正整数,保证区间不为空),询问是否在[x,y]区间内存在一个整数p,使得p*k属于[l,r],如果存在,则输出'YES',否则输出'NO'。(1<=l,r,x,y<=107)

·分析:

    首先看见了107,发现可以直接O(n)暴力枚举:枚举区间[x,y]的所有数,判断它与k的乘积是否在[l,r]中就可以了。从容AC:

 1 #include
 2 #include
 3 #define ll long long
 4 #define go(i,a,b) for(int i=a;i<=b;i++) 
 5 ll l,r,x,y,k,L,R;bool can=0;
 6 int main()
 7 {
 8     std::cin>>l>>r>>x>>y>>k;
 9     go(i,x,y)if(i*k<=r&&i*k>=l)can=1;
10     puts(can?"YES":"NO");
11     return 0;
12 }//Paul_Guderian

    其实在这之前大米饼首先想到的是O(1)的思路,即:利用[x,y]和k形成区间[x*k,y*k],然后判断该区间是否和[l,r]有交集。然后就笨笨地WA了。原因是这里只有整数点,新区间相邻点之间的间隔是k,可能[l,r]就夹在相邻两点之间并不接触两点,这样是NO而不是YES。例子如下:

image

     和它相似,只不过输出YES的例子就是这样:

image

           观察两种情况的差异,我们找出第一个比l大的点p1,再找出第一个比r小的点p2(点就是满足[x*k,y*k]又是k的倍数的点),我们可以发现第一幅图中位置p1>p2,第二幅图中p1

#include
#include
#include
#define go(i,a,b) for(int i=a;i<=b;i++) 
long long l,r,x,y,k,L,R;bool can=0;
int main()
{
    std::cin>>x>>y>>l>>r>>k;
    L=ceil(1.0*x/k);R=floor(1.0*y/k);
    if(L<=R&&!(Rr))can=1;
    puts(can?"YES":"NO");return 0;
}//Paul_Guderian

 

[C. Ilya And The Tree]

·述大意;
    
给出一棵树,共有n个结点(1<=n<=200000),并且输入每个点的点权w(1<=w<=200000)。每一个点有一个美丽值,计算方法是它到根节点的路径(包括它)的点权值的GCD。要求按1~n输出每个点的美丽值。但是有两个条件:①可以将路径上一个点的权值修改为0。②每个点求解独立(就是说求完一个点,树又恢复原样)。

·分析:

     值得注意的是求解独立,然后只能修改一个点的权值为0。

     求所有节点的GCD?我们脑袋里可能会浮现这样的图:

               image

    当然,白色的点表示我们将它变成0了(对于任意正整数a,GCD(a,0)=a)。这样看来我们要在这其中找到最优的GCD值。写DP难以转移,而且也不符合DP的要求。从数据范围来看,是可以使用"暴力"的方法求解的:

     对于每个点,我们都记录图中的所有情况GCD值,然后找到最大值就可以了,然而怎么找到个节点的所有情况——可以从它的父节点那里索取,即将父节点的每条情况链加入一个u,另一种是删掉当前的u(看图中一层一层的关系就可以了,这方法在代码中也很清晰)。

     具体的写法,网上多用set,大米饼用的是sort+unique,使用unique是因为不去重是会恰好MLE的

     代码来啦:

 1 #include
 2 #include
 3 #include
 4 #define _ (ans[u]=max(ans[u],t))
 5 #define go(i,a,b) for(int i=a;i<=b;i++)
 6 #define fo(i,a,x) for(int i=a[x],v=e[i].v;i;i=e[i].next,v=e[i].v)
 7 using namespace std;const int N=200001;
 8 struct E{int v,next;}e[N*2];vector<int>S[N];
 9 int n,a[N],head[N],k=1,t,ans[N];
10 int Gcd(int a,int b){if(a)while(a^=b^=a^=b%=a);return b;}
11 void ADD(int u,int v){e[k]=(E){v,head[u]};head[u]=k++;}
12 void Dfs(int u,int fa,int GCD)
13 {
14     if(S[fa].size())go(i,0,S[fa].size()-1)
15     S[u].push_back(t=Gcd(a[u],S[fa][i])),_;
16     S[u].push_back(t=GCD),_;GCD=Gcd(GCD,a[u]);t=GCD,_;
17     sort(S[u].begin(),S[u].end());  
18     S[u].erase(unique(S[u].begin(),S[u].end()),S[u].end());  
19     fo(i,head,u)if(v!=fa)Dfs(v,u,GCD);
20 }
21 int main()
22 {
23     scanf("%d",&n);
24     go(i,1,n)scanf("%d",a+i);
25     go(i,2,n){int u,v;scanf("%d%d",&u,&v);ADD(u,v);ADD(v,u);}
26     Dfs(1,1,0);go(i,1,n)printf("%d ",ans[i]);return 0;
27 }//Paul_Guderian

 

[D. Vitya and Strange Lesson]

·述大意:

     输入n个数ai和m个询问(1<=n,m<=300000,0<=ai<=300000),每个询问输入x,表示将所有数异或x后,求n个数的Mex(异或结果对后来的询问依旧有效)。

·分析:

     先说网络上常用的一个解法吧——Mex一出现,或许考虑Trie树

             由于log2300000约等于18.2,所以我们构建一个深度为20的01字典树。所谓01字典树,就是只有左右儿子分别表示01的字典树。并且从根结点到叶子结点是二进制从高位到低为排的。那么字典树的所有叶子结点可以表示1~219的所有整数。首先不考虑异或的情况,我们将一些数字按照二进制形式从高位(20位)到低位插入字典树,怎样快速得到Mex?由于数字的存在在树上体现为叶子结点的存在,如果前缀为000000000000000001_ _的数字都存在(即4,5,6,7都存在),在树上的表现为某一个子树是"饱满的"(可以理解最底层所有叶子结点都存在)。那么我们要找的答案肯定是在一颗不饱满的子树中,这个呢,可以拿一个4层的缩小版01字典树来加以说明:如果是饱满的树,应该长这个样子:

image

·这样就很清晰,那么某子树不饱满是啥?是这个样子:

image

·很明显我们要求的Mex值为12,但是为了方便查找,我们不妨将不饱满状态向上传递,使得包含它的子树都被标记为"不饱满":

image

·这样的标记关系形成后,我们就可以利用二叉树的性质对于每个询问log地查找Mex的值。可是,如何处理将全部数异或上x的情况(这是本题的特点)?为了使得字典树继续发挥作用,我们可以将x像那些数一样写成二进制形式,然后呢,如果在字典树的第k层的一个节点,x的二进制的k位是1,那么我们怎样表示所有数的这一位被取反了呢?那就是改变该层节点的左右儿子的位置,然后其他的就照常进行啊。

·我们通过异或的基本运算法则之一:a^b^c==a^(b^c)那么其实每一个修改值x,我们可以将当前的所有修改值异或到一起得到新的X,这样就可以在最初的字典树上进行操作了。

·如果懂了上述思路,那么接下来代码也不难,注意这里直接使用二进制跨过了建树,可思想是一致的。注意!很简洁!

 

 1 #include
 2 int n,m,a,b=1<<19,x,P=1,ans,t;
 3 bool full[30000008];
 4 void Up(int u)
 5 {
 6     if((!(u>>=1))||full[u])return;
 7     if(full[u<<1]&&full[u<<1|1])full[u]=1,Up(u);
 8 }
 9 int main()
10 {
11     scanf("%d%d",&n,&m);
12     while(n--&&scanf("%d",&a))full[a+b]=1,Up(a+b);
13     while(m--&&scanf("%d",&a))
14     {
15         x^=a;P=1;ans=0;t=19;
16         while(t--){P<<=1;
17         if((1<1])?ans|=1<1;
18         else if(full[P])ans|=1<1;}    
19         printf("%d\n",ans);    
20     }
21     return 0;
22 }//Paul_Guderian

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

苦苦安顿抚平的回忆,

骤然散落一如繁星的碎片......————汪峰《回忆之前忘记之后》


推荐阅读
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 本文介绍了一个程序,可以输出1000内能被3整除且个位数为6的所有整数。程序使用了循环和条件判断语句来筛选符合条件的整数,并将其输出。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
author-avatar
mobiledu2502894115
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有