vis

[bzoj4942]整数

我怕爱的太早我们不能终老 提交于 2019-11-26 20:49:29
考虑暴力,即需要考虑如何实现$\pm 2^{k}$,相当于要找到之后的第一个0或者之前的第一个1(维护区间是否全0/1即可),然后区间重置,可以用线段树维护,复杂度为$o(900n)$(a的划分和线段树),无法通过 但由于数据范围很大,这样过不了,可以想到压位,每30位二进制压为一个数,那么复杂度降为$o(30n)$(因为a只要划分为最多两个数)且常数变小,可以通过 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 1000100 4 #define L (k<<1) 5 #define R (L+1) 6 #define mid (l+r>>1) 7 #define S (1<<30) 8 int n,p,x,y,f[N],laz[N<<2],pos[N<<2],vis[N<<2][2]; 9 int pd(int k){ 10 if (!k)return 0; 11 if (k==S-1)return 1; 12 return -1; 13 } 14 void build(int k,int l,int r){ 15 laz[k]=-1; 16 vis[k][0]=1; 17 if (l==r){ 18 pos[k]=l; 19 return; 20 } 21 build(L,l,mid); 22

8.10 Round 1

走远了吗. 提交于 2019-11-26 19:58:05
要提高代码能力 T1:https://www.luogu.org/problem/T93255 送分背包 #include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<climits> #include<map> #include<queue> #include<cmath> using namespace std; #define O(x) cout << #x << " " << x << endl; #define B cout << "breakpoint" << endl; #define clr(a) memset(a,0,sizeof(a)); inline int read() { int ans = 0,op = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') op = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { (ans *= 10) += ch - '0'; ch = getchar(); } return ans * op; } typedef long long ll; const int N = 55;

hdu 1548 简单的bfs

风格不统一 提交于 2019-11-26 19:14:11
/*题目意思:有一个电梯,在第i层时,可以向上a[i]层,或向下a[i]层。 现在,给出你的初始位置,和终点位置问你最少操作几次可以到达,假设 无法到达输出“-1”。 思路:用bfs从起点开始存入队列开始搜,假设下一个点没有走过而且在 1~n层之间,则压入队列。符合条件则输出步数。 代码:*/ #include<iostream> #include<stdio.h> #include<queue> #include<algorithm> using namespace std; int n,s,d,a[10085],vis[1005];//vis[]标记是否走过 struct ww { int num; int step; }p1,p2;//用结构体记住位置和步数 int bfs() { memset(vis,0,sizeof(vis)); queue<ww>q; p1.num =s; p1.step =0; q.push(p1); vis[p1.num]=1;//起点压入队列 while(!q.empty()) { p2=q.front (); q.pop(); if(p2.num==d)//出口 return p2.step ; //向上时 if(p2.num+a[p2.num]<=n&&!vis[p2.num+a[p2.num]]) { //满足条件则步数加1,更新位置

洛谷 P1280 尼克的任务题解

╄→尐↘猪︶ㄣ 提交于 2019-11-26 19:13:59
题目链接: https://www.luogu.org/problem/P1280 题目描述 尼克每天上班之前都连接上英特网,接收他的上司发来的邮件,这些邮件包含了尼克主管的部门当天要完成的全部任务,每个任务由一个开始时刻与一个持续时间构成。 尼克的一个工作日为N分钟,从第一分钟开始到第N分钟结束。当尼克到达单位后他就开始干活。如果在同一时刻有多个任务需要完成,尼克可以任选其中的一个来做,而其余的则由他的同事完成,反之如果只有一个任务,则该任务必需由尼克去完成,假如某些任务开始时刻尼克正在工作,则这些任务也由尼克的同事完成。如果某任务于第P分钟开始,持续时间为T分钟,则该任务将在第P+T-1分钟结束。 写一个程序计算尼克应该如何选取任务,才能获得最大的空暇时间。 输入格式 输入数据第一行含两个用空格隔开的整数N和K(1≤N≤10000,1≤K≤10000),N表示尼克的工作时间,单位为分钟,K表示任务总数。 接下来共有K行,每一行有两个用空格隔开的整数P和T,表示该任务从第P分钟开始,持续时间为T分钟,其中1≤P≤N,1≤P+T-1≤N。 输出格式 输出文件仅一行,包含一个整数,表示尼克可能获得的最大空暇时间。 输入输出样例 输入 #1 复制 15 6 1 2 1 6 4 11 8 5 8 1 11 5 输出 #1 复制 4 题解 这题一般的解法都是DP。其实是可以用DFS暴力过的

图论--网络流--最大流 HDU 3572 Task Schedule(限流建图,超级源汇)

这一生的挚爱 提交于 2019-11-26 18:26:08
Problem Description Our geometry princess XMM has stoped her study in computational geometry to concentrate on her newly opened factory. Her factory has introduced M new machines in order to process the coming N tasks. For the i-th task, the factory has to start processing it at or after day Si, process it for Pi days, and finish the task before or at day Ei. A machine can only work on one task at a time, and each task can be processed by at most one machine at a time. However, a task can be interrupted and processed on different machines on different days. Now she wonders whether he has a

POJ - 3294~Relevant Phrases of Annihilation SPOJ - PHRASES~Substrings POJ - 1226~POJ - 3450 ~ POJ - 3080 (后缀数组求解多个串的公共字串问题)

烈酒焚心 提交于 2019-11-26 18:17:14
多个字符串的相关问题 这类问题的一个常用做法是,先将所有的字符串连接起来, 然后求后缀数组 和 height 数组,再利用 height 数组进行求解。 这中间可能需要二分答案。 POJ - 3294 题意: 给出n个串,求至少出现在n/2+1个串中的最长公共子串 题解: (摘自罗穗骞的国家集训队论文): 将 n 个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开, 求后缀数组。 然后二分答案,用和LCP将后缀分成若干组,判断每组的后缀是否出现在不小于 k 个的原串中。 这个做法的时间复杂度为 O(nlogn)。 你需要用一个id数组,记录S串的每个位置对于这哪一个串,然后二分每次用vis数组标记,查看那几个串出现过。 1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #include <cmath> 5 #include <algorithm> 6 #include <set> 7 #include <iostream> 8 #include <map> 9 #include <stack> 10 #include <string> 11 #include <time.h> 12 #include <vector> 13 #define pi acos(-1.0) 14 #define eps

经典网络流题目模板(P3376 + P2756 + P3381 : 最大流 + 二分图匹配 + 最小费用最大流)

落爺英雄遲暮 提交于 2019-11-26 18:12:59
题目来源 P3376 【模板】网络最大流 P2756 飞行员配对方案问题 P3381 【模板】最小费用最大流 最大流 最大流问题是网络流的经典类型之一,用处广泛,个人认为网络流问题最具特点的操作就是建反向边,这样相当于给了反悔的机会,不断地求增广路的,最终得到最大流 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<queue> #include<string> #include<fstream> #include<vector> #include<stack> #include <map> #include <iomanip> #define bug cout << "**********" << endl #define show(x,y) cout<<"["<<x<<","<<y<<"] " //#define LOCAL = 1; using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f; const ll mod = 1e6 + 3; const int Max = 1e5 + 10; struct Edge { int to, next, flow; /

Dijkstra的最小费用最大流问题

烂漫一生 提交于 2019-11-26 17:59:59
对于最小费用最大流问题,它的重点就在于 “增广路” 什么是 增广路? 就是在以找的的路的基础上再加一条路 加上这条路能让结果更大,直接使用 Dijkstra 能找的的路是最短的路,继续用能找到剩下路中间的最小路, 但是这两条路加上来不一定是总体的最小路 ,第一次 1->3 ->5->4->6 第二次1->2->6 这并不是我们需要的结果,所以在找第二条最短路时,我们需要能反悔,能不 让第一次不走3->5,怎么反悔,在构建图时加上一条反边,第一次走了多少正边减少多少反边加上多少,这样第二次就可以走5->3然后走3->6这条线,第一次走了3->5,第二次凑了5->3相当与反悔了第一次的路,这样就能尽可能的走最小路。 #include<iostream> #include<cstring> #include<queue> using namespace std; /*6 11 1 2 23 1 3 12 1 4 99 2 5 17 2 6 73 3 5 3 3 6 21 4 6 8 5 2 33 5 4 5 6 5 20*/ #define MAX 23060 int MinCos; int v,cnt; int Head[MAX]; int Next[MAX]; int F[MAX];//流量 int To[MAX];//终结的 int Dis[MAX]; int Cos[MAX];/

图论笔记

和自甴很熟 提交于 2019-11-26 17:52:17
目录 最小生成树 例题 怎么证明合数都可以分成素数的乘积 在最大生成树上求两点路径中边权的最小值 kruskal重构树 最短路 SPFA判负环 建图技巧 拓扑排序 queue优化 tarjian 差分约束 环套树/基环树 基环树找环 欧拉图 圈套圈算法 图论 最小生成树 $N$个城市,$M$条可修的公路,每条公路有一个修的成本$w_i$,要使$N$个城市连通,所需要的最低成本? 最少需要$N-1$条边,构成一棵树。 ## Kruskal算法证明 对图的顶点数$n$做归纳,证明$Kruskal$算法对任意$n$阶图都适用 归纳基础 $n=1$,显然能找到最小生成树 归纳过程 例题 P1550 [USACO08OCT]打井Watering Hole 思路就是建立一个超级源点往每个点建一条边权为$w_i$的边,然后跑最小生成树 怎么证明合数都可以分成素数的乘积 就不写了,我太菜了 在最大生成树上求两点路径中边权的最小值 int f[N][20]; //i的第2^j祖先 int mn[N][20]; //i往上跳2^j祖先所经过的边的最小值 int query(int u,int v) { int ans=inf; if(dep[u]>dep[v]) swap(u,v); for(int i=0,k=dep[v]-dep[u];i<=LG[k];++i) if(k>>i&1) { ans

[点分治] Luogu P2664 树上游戏

隐身守侯 提交于 2019-11-26 17:50:30
题解 对于树中的一点i,如果该点的颜色在该点到根这条链上是第一次出现,那么对于这棵树的其他点j(以i和j的lca为根),均能与i的子树(包括i)组成点对,i的颜色会对j的答案贡献size[i] 然后点分治就可以解决了 代码 1 #include <cstdio> 2 #include <iostream> 3 #define ll long long 4 using namespace std; 5 const int N=2e5+10,inf=1e8; 6 int n,cnt=1,root,head[N],v[N],vis[N*2]; 7 ll q,sum,num,tot,Mx=inf,size[N],col[N],ans[N],p[N]; 8 struct edge { int to,from; }e[N*2]; 9 void clear(int x,int fa) { p[v[x]]=col[v[x]]=0; for (int i=head[x];i;i=e[i].from) if (!vis[i]&&e[i].to!=fa) clear(e[i].to,x); } 10 void insert(int x,int y) 11 { 12 e[++cnt].to=y,e[cnt].from=head[x],head[x]=cnt; 13 e[++cnt].to=x,e[cnt]