sgt

高一考试的题解

不想你离开。 提交于 2020-12-28 20:03:51
本学校高一同学又迎来了一次考试。 本蒟蒻身为验题人,自然要写一个题解来帮助大家(骗访问量)啦。 T1: 显然满足条件的数mod m相同,这样我们开m个vector把mod m相同的数放进同一个vector里。能否有解判断size即可。 答案要求字典序最小,我们比较这些vector的第一个元素(最小的),显然它们两两不可能相同,所以判断它们的大小即可比较字典序。 (话说这题后70分数据是我造的,前面30分队长说有两个"No",某人排序反了只有20,说明我还把他WA了,嗯,没出锅) 代码: 1 #include<bits/stdc++.h> 2 const int maxe=1e6+ 1e2; 3 4 std::vector< int > v[maxe]; 5 6 int main() { 7 static int n,m,k,t,sel=- 1 ; 8 scanf( " %d%d%d " ,&n,&k,&m) , assert(m&&m<= 1e6); 9 while (n--) scanf( " %d " ,&t) , v[t% m].push_back(t); 10 for ( int i= 0 ;i<m;i++ ) { 11 if ( v[i].size() ) std::sort(v[i].begin(),v[i].end() ); 12 if ( (signed) v[i]

洛谷T3401 洛谷树 树剖&&分治

☆樱花仙子☆ 提交于 2020-04-30 04:16:01
这道题好干燥啊。。。折腾了半个月。。。感谢bogo大佬对我的指导。。。 题目要求支持的操作:1.查询某段路径的所有子路径的xor值之和;2.修改某条边的权值。重点是操作1。 刚开始,我看到了操作1之后就不自觉的想到了非~常暴力的东西。。。还好大佬及时把我引上正途:分治! 大家知道,最大子段和有个分治算法,本题的方法就跟这个比较类似。 对于一段子路径,若它能对答案产生贡献,那么它要么完全在左儿子中,要么完全在右儿子中,要么跨越左右儿子。 对于每段路径,我们需要记录如下变量:yh:异或和,ans:答案,就是要查询的东西,p0[i]:此序列的前缀序列中,异或和的二进制第i位为0的序列有多少段,后面的p1,s0,s1类似。 于是,在分治的合并阶段,答案便分为两个部分:第一部分是左右儿子返回的ans;第二部分是左儿子的s0[i]*p1[i]和s1[i]*p0[i],这两个结果还要再乘以(1 << i),表示有多少段跨越左右儿子的子路径的xor值的二进制第i位为1,乘上(1 << i)之后就表示答案实际应该累加的值。因为0和1、1和0异或的结果是1嘛,因此就对答案产生了贡献。 我们当然也要维护p0、p1、s0、s1。这里较上面简单一些,细节详见代码的rg_a结构体定义部分。 以上讨论的都是链上的做法,题目给定的是一棵树,那么树剖就Ok了,之后扔到线段树里大力merge即可~ 对于修改操作