同上一题一样,记录dfs遍历的序列,然后再利用树状数组快速求和调了好久呢View Code #include<cstdio>#include<stack>#include<cstring>using namespace std;stack<int> ss;const int maxn = 100010;struct EDGE{ int v,next;}edge[maxn*2];int exis[maxn],head[maxn],l[maxn],r[maxn],seq[maxn*2],re[maxn],c[maxn*2],cnt;bool vis[ Read More
一棵树,求每个结点的子树中有几个数是小于这个数的dfs会进入一个点一次,出一个点一次,中间经过的点都是它的子树中的点,所以,进入的时候统计一遍,出来的时候统计一遍,两个结果相减就可以了纯dfs会爆栈,要模拟栈。不过,不模拟栈也可以过,在网上看到c++可以设置栈的大小,所以把栈空间设置的大一点直接dfs做就可以了View Code #pragma comment(linker,"/STACK:100000000,100000000")#include<cstdio>#include<cstring>const int maxn = 100010;str Read More
线段树做法,成段求和,单点更新View Code #include<cstdio>#include<cstring>#include<map>#include<algorithm>using namespace std;const int maxn = 50010;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1__int64 sum[maxn<<2];struct node{ int l,r,id;}p[200010];map<int,int> ha Read More
离线处理询问,即先记录下所有询问用map将当前的值映射到一个下标,如果以前已经映射过了,则在树状数组中取消在上一次的位置的记录再在当前位置加入当前值,这样的话对于每个询问便可以先更新再查询,离线记录结果View Code #include<cstdio>#include<cstring>#include<map>#include<algorithm>using namespace std;const int maxn = 50010;__int64 c[maxn];struct node{ int l,r,id;}p[200010];map< Read More
中等的模拟题,各种暴力枚举可以用来锻炼代码能力View Code #include<cstdio>#include<cstring>#include<algorithm>using namespace std;struct DD{ char s[25];}dic[120];int cmp(DD a,DD b){ return strcmp(a.s,b.s)<0;}char query[100];char ss[100][100];bool judge(char *query,char *dic){ char unsign[100]; char pos[ Read More
http://www.notonlysuccess.com/index.php/alibaba/做不出来,参考了not。。。。的解释,懂了,敲完发现,与他的代码几乎一样。。。。。题意很简单,成段更新,成段询问,但是更新却和一般的线段树大不一样,每个点虽然接收到相同的信息,但是由于本身不同,最终得到的值也是不同的.用一般的延迟操作就搞不定了.突破点在K,范围很小,只有10,可以考虑每次有人升级的时候,就递归的找下去,将这个人进行升级操作.由于找到某个人只需要logn的复杂度,每个人最多升k次,所以n个人的复杂度是O(nklogn)用了两个辅助数组add[maxn]和MAX[maxk][maxn] Read More
同poj 2482 不过这里在边界上的点也算在矩形内,边界处理注意一下就好了View Code #include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1const int maxn = 2001;int cover[maxn<<2],Max[maxn<<2];struct seg{ double l,r,h; int flag; Read More
一个小小的bug搞了将近两天,郁闷shi了平面上有很多点,每个点有一个权值,给定一个矩形,求出用这个矩形去套时所能同时套住的点的权值的和的最大值转换成线段树:以每个点为左下角向右延伸转换成一个矩形,对x轴建树,一个点就相当于两条线段,一条权值为v,另一条权值为-v,线段树维护总的区间内最大的覆盖次数,把每次的Max[1]与ans比较,能更新就更新。具体为什么这样,用笔和纸画画,仔细想想应该能想出来,我开始也是不清楚,结果在纸上把各种情况一模拟,就清楚了View Code #include<cstdio>#include<cstring>#include<algor Read More
求一段连续的区间,使其在满足 和 对p取余不超过k的 前提 下 和最大 。做法:用线段树维护区间最小值,最小的下标,即最左边,因为加入sum[i]%p>k就要减去一个sum[id] , sum[id]%p在【sum[i]%p-k,sum[i]%p】之间,sum[i]-sum[id]的值就为以i结尾的满足条件的连续的一段数的最大值,所以id要尽可能小,所以就是求值在【sum[i]%p-k,sum[i]%p】之间的最左边的数的下标,即满足条件的数的下标最小值。每次更新时把进过的结点的下标最小值(如果能更新)都更新一遍View Code #include<cstdio>#inclu Read More
将线段树从左到右排序,然后从左往右依次添加线段,用一个vector记录能看到当前线段的线段编号,最后暴力统计一个小小的bug查了半天 memset(Hash,-1,sizeof(Hash))写成了memset(hash,-1,sizeof(-1));然后再测数据时一直没有发现初始化的问题,就悲剧了一个晚上,看来以后把memset写在宏定义里也不失为一个防止出错的选择View Code #include<cstdio>#include<cstring>#include<vector>#include<algorithm>using namespac Read More