- 博客(52)
- 收藏
- 关注
原创 线段树基础题
1. POJ - 3468#include<iostream>#include<cstdio>using namespace std;typedef long long LL;const int N=1e5+10;struct Node{ int l, r; LL sum, add;};void push_up(int u);LL query(int u, int l, int r);void modify(int u, int l, int r
2022-03-29 21:29:32
657
原创 2021CCPC河南省赛题解(主席树+二分)
考场没看见随机化数据,写了一个主席树+二分,但是之前练习的时候没有做过多实例,忘记初始化上层用到的所有节点信息了, wa麻了。 思路:主席树+二分, O(nlogn^2) 二分距离当前点最近的,大于等于a[i]的数的个数最靠右的位置, 然后利用主席树区间询问在mid到i-1这段大于x的数的数量, 作为check函数 ```cpp#include<iostream>#include<algorithm>#include<cstdio>#includ
2021-10-31 13:16:02
788
1
原创 HDU 4553 约会安排 (超详解)
高亮查看一. 题目二. 代码 由题知,我们需要知道是否存在一段连续区间,即线段树维护最大子段长度。 maxv, pre, lat:最大子段长度, 最大前缀, 最大后缀,详见代码 fa, ls, rs:父, 左儿子, 右儿子。 fa.maxv=(ls.lat+rs.pre, max(ls.maxv, rs.maxv)); fa.pre=ls.pre+(ls.pre==左区间长度?rs.pre:0); fa.lat=rs.lat+(rs.lat==右区间长度?ls.lat:0); 此外,还
2021-09-22 15:30:09
178
原创 Edge of Taixuan
一. 题目高亮代码 给定n个点, m个区间, 每个区间有l, r, w, 代表会对l到r内的所有点对连一条长度为w的边。 问最多能去掉边和多长,使得剩下的点都和1号点直接或者间接相连。 如果有点,不能和1连通,输出不行。二. 思路 每次操作会使用(r-l+1)*(r-l)/2*w的长度(所有点*能组成的对的点)/2是去除重复的,*w是每对的长度。 可以算出来总使用长度, 然后减去使所有点相连的最短长度,剩下的就是可以去除的最大长度。 将点上的值当成与他后面点相连的边的长度。
2021-09-20 18:38:28
475
2
原创 2021河南ICPC Alice and Bob
一. 题目二. 思路三. 代码#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<unordered_map>using namespace std;typedef long long LL;const int N=1e5+10;int tfind(int l, int r, int x);void init(
2021-09-17 19:04:07
199
原创 蓝桥杯 剪邮票(超详解)
思路:二进制枚举所有情况dfs判断连通块(或者可以枚举,五个数的组合数,然后判断是否联通)#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int N=20;bool check(int state);bool check1(int state);int lowbit(int x);void dfs(int x, int y);int ans;
2021-04-01 21:22:15
248
原创 HDU 5023(线段树染色)(两种方法)(非状压,巧妙得到状态)(状压得到状态)(超详解)
思路:用线段树去维护,修改的区间,并染上色。当询问某一个区间时,可以把当前区间内的所有色全存到数组里,最后排序去重,输出。#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<vector> using namespace std;typedef long long LL;const int N=1e6+10;struct
2021-03-29 20:58:24
262
原创 蓝桥杯第十届 数的分解(1秒以内搜索, dfs)
#include<iostream>#include<cstdio>using namespace std;void dfs(int u, int st);bool check();int ans;int path[10];//存储选择的三个数signed main(){ dfs(0, 1); cout<<ans<<endl;}//给其选择定一个顺序,从小到大,以免重复搜索void dfs(int u, int st){ if
2021-03-24 23:29:54
145
转载 HDU 1540 地道战(超详解)
思路:将完好村庄当成1,被破坏的村庄当成0,找到连续1,即可。1.需要维护的信息左右端点(l, r)最长区间长度(maxl)该区间的最长前缀和最长后缀,原因如下(pre, lat)2.最长区间怎么求取,该节点左儿子的最长长度,和该节点右儿子的最长长度,和左儿子的最长后缀➕右儿子的最长前缀的最大值这也是上面维护信息的原因3.push_up怎么写显然最大值是上面所描述的但是,最长前缀后缀怎么求:以最长前缀为例,该节点的最长前缀可能就是左儿子的最长前缀,或者是左儿子的区间长度加上右儿子的最长
2021-03-18 00:53:57
663
原创 递增三元组(超详解)(三种做法)
思路:由于a数组与c数组的取值都受b数组影响,所以可以枚举b【I】,然后在枚举a数组有多少个数小于b[i],c数组中有多少数大于b[i],则当前b[i]合法方案为[c中大于b[i]个数乘a中小于b[i]的个数],可以通过前缀和或二分或双指针去找到小于b[i]的第一个数,大于b[i]的第一个数1.前缀和#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>usin
2021-03-14 12:38:39
4177
16
原创 即将到来的新生赛
思路:数据很小,直接dfs暴力就能过。按右端点从小到大排序,以便保证当前这个点的r>=上一个选的点的l的同时,也大于之前选的所有点.path数组存储选不选当前点。或者也可以,二进制枚举,把每个任务选不选看成一个状态,最多有(1<<20)-1种状态#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<vector>
2021-03-12 20:21:58
124
原创 结果填空:马的管辖(超详解版)
思路:二进制枚举所有马的状态,然后遍历所有马,标记其管辖点,最后判断当前方案是否合法#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int N=10, INF=0x3f3f3f3f;bool in(int a, int b);//判断越界 bool judge();//判断方案是否合法 void get(int k, int &start, i
2021-03-10 22:56:56
208
原创 飞行员兄弟(二进制枚举, 详解)
思路:将4*4矩阵每一个位置看成一个状态,总共有2^16次方种状态,暴力枚举每种状态即可#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<algorithm>#define f first#define s secondusing namespace std;typedef pair<int, int> PII;co
2021-03-09 23:47:28
182
原创 小H的奇怪加法
#include<iostream>#include<cstdio>#include<string>#include<vector>#include<unordered_map>#include<algorithm>#define f first#define s secondusing namespace std;typedef long long LL;LL s1, s2;string sys;unorde
2021-03-09 12:30:09
105
原创 带分数(两种做法, 详解(暴力+优化))
暴力#include<iostream>#include<cstdio>#include<algorithm>using namespace std;const int N=15;int get_val(int l, int r);//得到当前全排列l, r段的值void dfs(int u);int n;int res;int num[N];//存储全排列bool st[N];//判断是否用过当前的数signed main(){ .
2021-03-05 21:04:12
229
原创 电路维修(双端队列, 带图详解)
思路:将无需改变的边看成边权是0, 将需要改变的边看成边权是1.本题可以看成一个弱化版的dijkstra求最短路,则可以采用双端队列,每次从当前点扩展别的点时,若扩展到的点边权是0则放对头,如果是1则放队尾。由于队头每次是边权最短的点,则最终点一定是最短路(原理同dijkstra, 每次取出边权最短的边)原图是字符二维数组,可以把节点想象出来,不用存储、、、、、、、、、、、、、、、、、#include<iostream>#include<cstdio>#include
2021-03-04 21:33:39
396
2
原创 魔板(利用map, 非康拓展开->详解)
思路:将初始状态和目标状态看成两个 点状态 ,然后利用bfs求最短操作次数!ABC顺序操作,得到的答案一定是字典序。#include<iostream>#include<cstdio>#include<string>#include<queue>#include<algorithm>#include<unordered_map>#define f first#define s secondusing namespac
2021-03-03 21:26:08
124
2
原创 第九届蓝桥杯 倍数问题(背包问题,超详解,三维可过,二维可过代码)
闫氏DP分析法:假定模m状态表示:f[i][j][k]表示从前i个物品中选,选j个,余数是k的所有方案数。存值是最大值状态计算公式:所有方案可以 不重不漏 分为两类:选第i个,和不选第i个数。不选第i个的方案,相当于从前i-1个选,选j个,余数是K:f[i-1][j][k]选第i个数的方案,假定去掉第i个,这时最大值还是原本就是最大值得那一种方案,公式:f[i-1][j-1][(k-a[i])%m]+a[i]第三维推导:设x是除掉a[i]的数的和,则原来是(x+a[i])%m=k .
2021-02-25 14:50:13
823
原创 最大公约数
#include<iostream>#include<cstdio>#include<algorithm>#include<map>using namespace std;typedef long long LL;const int INF=0x3f3f3f3f, N=1e5+10;LL gcd(LL a, LL b);int n;LL a[N];map<LL, LL> vn, temp;//gcd映射成下标 //区间内不同
2021-02-18 20:49:36
110
原创 最大公约数和最小公倍数问题
#include<iostream>#include<cstdio>using namespace std;typedef long long LL;LL gcd(LL a, LL b);LL res;LL x, y;//以y为最小公倍数,则满足条件的数一定小于y。 signed main(){ cin>>x>>y; LL t=x*y; for(LL i=1;i<=y;i++) if(t%i==0&&gcd
2021-02-18 20:48:31
87
原创 最大公约数与最小公倍数
#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>using namespace std;int gcd(int a, int b);int a, b;signed main(){ cin>>a>>b; //x*y==a*b. //乘积为定值时,两个数越接近根号积,和越小 int t=a*b, h=(int)sqrt(t
2021-02-18 20:47:06
54
原创 小x的质数
#include<iostream>#include<cstdio>using namespace std;const int N=1e7+10;void get_primes(int n);int pre_sum(int l, int r);int q;bool st[N];int primes[N], cnt;int sum[N];signed main(){ get_primes(N);//把非质数置为true for(int i=0;i&l
2021-02-18 20:45:34
147
原创 质数和
#include<iostream>#include<cstdio>#include<algorithm>using namespace std;typedef long long LL;const int N=1e5+10;void get_primes(int n);int a, b;bool st[N];int primes[N], cnt;signed main(){ get_primes(N); cin>>a>
2021-02-18 20:43:21
86
1
原创 质数的和与积
#include<iostream>#include<cstdio>using namespace std;typedef long long LL;const int N=1e4+10;void get_primes(int n);int n;LL res;bool st[N];int primes[N], cnt;signed main(){ get_primes(N); cin>>n; for(int i=n/2;i<=
2021-02-18 20:42:08
599
原创 程序设计:找质数
#include<iostream>#include<cstdio>using namespace std;const int N=1e6+10;void get_primes(int n);int T;int n;int cnt, primes[N];bool st[N];//筛一遍质数,在从小到大枚举。 signed main(){ get_primes(N); cin>>T; while(T--) { scanf("%d"
2021-02-18 20:40:52
172
原创 约数之和
#include<iostream>#include<cstdio>#include<unordered_map>using namespace std;const int mod=1e9+7;typedef long long LL;int n;unordered_map<int, int> primes;//质因子值映射成指数大小void divide(int x){ for(int i=2;i<=x/i;i++)
2021-02-18 20:39:41
323
原创 约数个数
#include<iostream>#include<cstdio>#include<unordered_map>using namespace std;const int mod=1e9+7;typedef long long LL;int n;unordered_map<int, int> primes;//因数值映射成指数值void divide(int x){ for(int i=2;i<=x/i;i++)
2021-02-18 20:38:02
48
原创 Codeforce 1490C Sum of Cubes
思路:最开始,一看到x最大是1e12,想着用二分去写,可惜太菜了,二分条件没想出来。后来又发现,三次方和是等于x,所以最多枚举到1e4,这样就可以用双指针去做了。然后还可以优化,不用每次都从1e4向前枚举,只需要从(int)pow(x, 1.0/3)+1(x的根号3次方)向前枚举即可。#include<iostream>#include<cstdio>#include<cmath>using namespace std;typedef long long L
2021-02-17 01:04:12
276
原创 Codeforce 1490B Balanced Remainders
思路:先去统计原数组,除以3余数为0, 1, 2的个数。然后,在一重循环,当c0!=c1!=c2时就执行,观察发现,每次只需贪心的让三个数中最大的数去减少即可,又发现,如果c0最大,则让c0–(让一个余数是0的数加1即可),这样c1就会++,另外两个依此类推。#include<iostream>#include<cstdio>#include<algorithm>using namespace std;const int N=3e4+10;int T;
2021-02-17 00:54:55
634
原创 codeforce 1490A Dense Array
思路:只需要遍历一遍数组,去判断当前这个数和下一个数的商是不是大于2即可,若大于2,则需要贪心去每次增加一个两个数中较小的数的乘2,的数,然后用新数和较大的那个数在看商是不是大于2,直到小于2,停止循环。#include<iostream>#include<cstdio>#include<algorithm>using namespace std;const int N=55;int T;int n;int a[N];signed main(){
2021-02-17 00:47:56
266
原创 地毯
#include<iostream>#include<cstdio>using namespace std;const int N=1010;void add(int x1, int y1, int x2, int y2, int c);int n, m;int a[N][N], b[N][N];int main(){ cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=.
2021-01-21 21:02:42
74
原创 HDU1556
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int N=1e6+10;int n;int b[N];int main(){ while(scanf("%d", &n), n) { memset(b, 0, sizeof b); for(int i=1;i<=n.
2021-01-21 21:01:44
65
原创 HDU6514
#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<string>#include<algorithm>using namespace std;int n, m;int p, q;int main(){ while(scanf("%d%d",&n,&m)!=EOF) { vector&.
2021-01-21 21:00:53
155
原创 POJ 3263
#include<iostream>#include<cstdio>#include<map>#include<cstring>using namespace std;typedef pair<int, int> PII;const int N=1e4+10;void add(int l, int r, int c);int n, i, h, r;int b[N];map<PII, bool> ok;int .
2021-01-21 20:57:39
86
1
原创 铺设道路
#include<iostream>#include<cstdio>#include<algorithm>using namespace std;const int N=1e5+10;int n;int res;int d[N];int main(){ cin>>n; for(int i=1;i<=n;i++) { scanf("%d", &d[i]);//如果a[i]>a[i-1],则a[i-1]可以.
2021-01-21 20:56:34
317
原创 校门外的树
#include<iostream>#include<cstdio>using namespace std;const int N=1e4+10;void add(int l, int r, int c);int len;int m;int a[N], b[N];int main(){ cin>>len>>m; for(int i=1;i<=len+1;i++) add(i, i, 0); while(m--) { .
2021-01-21 20:55:48
65
原创 高低位交换
#include<iostream>#include<cstdio>using namespace std;typedef long long LL;void solve(LL x);LL x;int main(){ cin>>x; solve(x); return 0;}void solve(LL x){ LL pre=x>>16;//pre=00000..0000-xxxxxxx LL later=x-(pr.
2021-01-21 20:54:56
98
原创 筷子大作战
#include<iostream>#include<cstdio>using namespace std;const int N=5e6+10;int n;int l;int res;int main(){ cin>>n; while(n--) { int x; scanf("%d", &x);//相同异或为0, 不同异或为1. res^=x; } cout<<res<<endl; .
2021-01-21 20:53:00
763
原创 差分与位运算
差分1.定义:一维:原数组a与差分数组b,a是b的前缀和。a[i]=b1+b2+b3..+bi;二维:原数组a[i, j], 差分数组b[i, j]。a是b的前缀和。2.作用:用o(1)时间给原数组某一部分加上一个值3.构造将原数组重新插入一遍add(i, i, c), add(i, j, i, j, c)4.注意下标从一开始5.步骤构造差分数组->加c->求差分数组的前缀和,得到加完后的a数组6.模板一维:b[l]+=c,b[r+1]-=
2021-01-20 13:27:10
215
原创 CF581C
#include<iostream>#include<cstdio>#include<algorithm>using namespace std;const int N=1e5+10;void solve();int res; int n, k;struct Ac{ int v, d;//存值和距离 bool operator<(const Ac &W)const { //这样技能等级/10才能最大 .
2021-01-20 13:17:07
57
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人