cstring

HNOI2018

坚强是说给别人听的谎言 提交于 2021-02-10 02:26:45
为什么HN今年风格也这么诡异呀。 先给个Achen的题解链接: http://www.cnblogs.com/Achenchen/p/8921650.html ,我的题解太简略了。 D1T1 我觉得这是一道很有趣的题呀 如果第i个数之前的运算符是and,则这一位设为1,否则为0,得到的二进制数记为xx。 对每一位分别考虑,对于第i位,如果第j个数是1,那么这一位设为1,否则为0,得到的二进制数记为$b_i$。 以左边为最低位,按前缀归纳容易证明,第i位的结果为1,当且仅当$x < b_i$ 我们将b从大到小排序,结果设为c,那么答案不为零仅当在c的顺序下,r中没有任何0在1的前面。 找到r中第一个0的位置,假设是k,那么解x要满足$c_k≤x<c_{k–1}$,于是答案是$c_{k – 1} – c_k$ //Serene #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; #define ll long long #define db double #define For(i,a,b) for(int i=(a);i<=(b);++i) #define Rep(i,a,b)

HNOI2018

女生的网名这么多〃 提交于 2021-02-10 02:26:11
d1t1[HNOI/AHOI2018]寻宝游戏 感觉很神,反正我完全没想到 分开考虑每一位,对于每一位i计算一个二进制数b[i], 对于第i位,从后往前第j个数这一位是1,那么b[i]^=(1<<j) 对于操作,从后往前考虑每个数前面的符号,把&看成1,|看成0 把一个操作序列看成一个二进制数c 发现|0和&1等于无影响,一个操作序列的最后一个|1或者&0决定结果的值 那么对于第i位,要使这一位为1,必须满足c<b[i] (这一位是1,则要选择一个b[i]中是1的位置取|,并将它之前的所有操作任意取,之后的操作有唯一取法,相当于将二进制位中某个1变成0,高位不变,低位任意取,最后得到c<b[i]) 那么将b从大到小排序,对于每个询问,首先满足找到最靠左的0必须在1后面,然后最靠左的0的位置为pos,答案为b[pos-1]-b[pos] 要取模,一开始傻乎乎地在那里写高精... 1 // Achen 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdlib> 6 #include<vector> 7 #include<cstdio> 8 #include<queue> 9 #include<cmath> 10 #define For(i,a,b) for(int i=(a);i<

归并排序求逆序对

橙三吉。 提交于 2021-02-09 09:58:50
什么是逆序对: 设 A 为一个有 n 个数字的有序集 (n> 1 ),其中所有数字各不相同。 如果存在正整数 i, j 使得 1 ≤ i < j ≤ n 而且 A[i] > A[j],则 <A[i], A[j]> 这个有序对称为 A 的一个逆序对,也称作逆序数。 如果还是不懂请点 这里 怎么求逆序对: 求逆序对就需要先介绍一种排序方法: 归并排序: 归并排序是利用归并的思想实现的排序方法,该算法采用经典的分治策略分治法将问题分成一些小的问题然后递归求解. 举个例子: 输入n个数,要求从大到小排序: 【思路】:利用分治发(二分),从中间分开,再把左右依次分开,始终让小区间内的数从小到大,那么这是分治的思想(分而治之) 图解(来自dreamcatcher-cs的博客 ): 让后利用一个新的数组把数据放过去,让后再放回来 代码: #include<iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <vector> #include <map> #include < string > #include <cstring> using namespace std; const int maxn= 999999999 ;

归并排序+归并排序求逆序对(例题P1908)

本秂侑毒 提交于 2021-02-09 09:50:18
归并排序(merge sort) 顾名思义,这是一种排序算法,时间复杂度为O(nlogn),时间复杂度上和快排一样 归并排序是分治思想的应用,我们先将n个数不断地二分,最后得到n个长度为1的区间,显然,这n个小区间都是单调的,随后合并相邻的两个区间,得到n/2个单增(减)的区间,随后我们继续合并相邻的两个区间,得到n/4个单增(减)的区间.... 每次合并操作的总时间复杂度为O(n),logn次合并用时O(logn),故总时间复杂度为O(nlogn) 合并操作比较好理解,就像下图这样二分区间即可(红线代表分割线): 然后,我们要如何实现O(n)的复杂度实现区间合并呢? 我们另开一个大小和原数组a大小一样的数组alt,存储需要合并的两个区间的数,方便起见,我们用pos代表alt数组的当前指向的位置,用i表示左区间当前所指的位置,用j表示右区间当前所指的位置,如下图所示: 记此时我们合并形成的区间为[l,r],按升序排序,那么我们枚举这一区间中的pos,每次比较alt[i]和alt[j],如果alt[i] < alt[j] 那么令a[pos] = alt[i],同时pos++,i++ ,否则令a[pos] = alt[j] ,同时pos++,j++,如果左区间的数已经全部遍历,那么将右区间剩下的数依次加入pos位置,反之同理,操作过程如下图所示: 至此,区间[l,r

欧拉回路,欧拉路径(收录

穿精又带淫゛_ 提交于 2021-02-08 23:54:21
介绍的内容 博客2 题目: 欧拉回路 题意:   欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路。现给定一个图,问是否存在欧拉回路? #include<iostream> #include <cstdio> #include <cctype> #include <algorithm> #include <cstring> #include <cmath> #include < string > #include <cmath> #include < set > #include <vector> #include <stack> #include <queue> #include <map> using namespace std; #define ll long long #define mem(a,x) memset(a,x,sizeof(a)) #define se second #define fi first const ll mod= 998244353 ; const int INF= 0x3f3f3f3f ; const int N=2e5+ 5 ; int n,m; int du[ 1005 ]; int f[ 1005 ]; int getf( int x) { if (x!= f[x]) { f[x] = getf(f[x]);

noip模拟测试11

好久不见. 提交于 2021-02-08 23:02:27
T1:string   第一眼秒出思路,这不就是排序那道题的加强版吗?   然而歪?解复杂度虽然是对的,但常数过大,竟被卡到70   歪?解:(实际上std写的就是这个,但据说std被卡掉了 OAO)     因为字符集很小,所以我们可以把区间排序改为区间查询和覆盖     即:先查询区间内所有字符的个数,再从左端点开始按照大小关系依次将长度为字符个数的区间修改为该字符。     期望复杂度O ( 26*mlogn ),实际复杂度O ( 26*mlogn*( 巨大的常数 ) )     所以需要一(feng)定(kuang)的卡常   正?解:     因为字符集很小,所以重复字符很多,又因为我们的操作是排序,所以操作后字符显然会变为一块一块的     所以可以在线段树上每个节点记录段内字符是否全部相等     若相等直接return,否则向下递归     这样直接递归看起来似乎单次复杂度不太对     但是仔细一想会发现,对于较短的区间操作来说,整块字符较少,递归次数较多,但区间短,所以复杂度正确               对于较长的区间操作来说,整块字符较多,递归次数较少,虽区间长,但复杂度仍正确     所以均摊复杂度正确,可过(还跑的挺快???)          so,歪?解 code 1 #include<cstdio> 2 #include<iostream> 3

getting the length of an array using strlen in g++ compiler

淺唱寂寞╮ 提交于 2021-02-04 18:55:07
问题 could someone explain why i am getting this error when i am compiling the source using following g++ compiler #include <cstdio> #include <string> using namespace std; int main() { char source_language[50]; scanf("%16s\n",source_language); int length = sizeof(source_language); int sizeofchar = strlen(source_language); printf("%d\n",sizeofchar); } this gives me following error test.cpp: In function ‘int main()’: test.cpp:31: error: ‘strlen’ was not declared in this scope when i change the

牛客网

你。 提交于 2021-01-27 03:51:28
排序 - 爱奇艺 https://www.nowcoder.com/practice/e496d8e885a949d18476b2dea1e594a9?tpId=90&tqId=30794&tPage=1&rp=1&ru=%2Fta%2F2018test&qru=%2Fta%2F2018test%2Fquestion-ranking 题目描述 牛牛有一个长度为n的整数序列,牛牛想对这个序列进行重排为一个非严格升序序列。牛牛比较懒惰,他想移动尽量少的数就完成重排,请你帮他计算一下他最少需要移动多少个序列中的元素。(当一个元素不在它原来所在的位置,这个元素就是被移动了的) 输入描述: 输入包括两行,第一行一个整数n(1 ≤ n ≤ 50),即序列的长度 第二行n个整数x[i](1 ≤ x[i] ≤ 100),即序列中的每个数 输出描述: 输出一个整数,即最少需要移动的元素个数 示例1 输入 复制 3 3 2 1 输出 复制 2 思路:先将数组备份到y,再将x排序,最后逐位比较x与y不同的数字个数 #include<cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; #define N 50 int main() { int n, x[N], y[N]; cin

高精除以低精

我是研究僧i 提交于 2021-01-25 06:51:05
1128: 高精度 高精度除法 题目描述 计算n/m的值,设n,m为整数,n的长度小于等于1000,m的长度小于等于15位,要求精确到小数点后500位。如果整数位为零,则省略小数点前的零 输入 两行,每行一个整数 输出 一行,保留500位小数的实数。 样例输入 355 113 样例输出 3

2019山东省赛B

若如初见. 提交于 2021-01-24 11:48:35
题意:   初始有n个灯泡,灯泡状态是0和1,。现在有k轮操作,每次改变且仅改变m个的灯的状态,给定n盏灯的初始状态的最终状态,求有多少种解决改变灯的方案满足可以满足题目条件。 思路:   开始写的时候以为是组合计数和容斥原理什么鬼的,后来发现n,m,k的值都比较小,觉得应该是三维dp了,当然是瞎想,最后看题解还是一个二维dp可以解决的问题,只不过是三重循环。给队友lrr说了一下题解的状态定义,他也较快就写出来了。其实对于灯的状态,每次改变一次之后,现在的问题和之前的问题形式一样,只是k值和目标灯的状态不同的个数变了。   状态如下定义dp【i】【j】表示操作到第 i 轮,与目标的灯的状态不同的个数为 j 的操作方案数量。初始化dp[k][0]=1,dp[k][others]=0。倒退dp的状态转移,对于第k-1次,他的方案数是第k次全部的dp数组(即dp【k】)中转移而来的。对于dp[k][j],与目标状态j的不同,n-j个相同,设改变j个中的x个,改变n-j个中的y个(这里要求x+y=m&& j-x+y=kk)(kk为dp【k】中与目标状态不同的个数为kk)。这样可以解出x和y,当x和y满足为整数并且x<=j&&y<=n-j 即为合理的转移方案。这样dp转移就不存在什么重复计数的问题,因为都是一种存在的状态变化而来的,计算出到达每种状态的方案数量,最后的答案就是dp[0]