
数据结构
文章平均质量分 70
Benzema67
北京邮电大学学生
展开
-
线段树基本题型总结
线段树解决序列上修改查询问题,可以完成下面三种操作:1、更新点查询区间;2、更新区间查询点;3、更新区间查询区间涉及到更新区间(成段更新)时,有一个技巧lazy_tag,在线段树子树加上tag,表示这个子树包含某些性质或者要进行某些操作,不用立即访问到这个子树的叶子,只有当下一次仍需访问这个子树下的节点时才继续进行。lazy_tag技巧可以用于下面几个方面:1、区间加一个数。(这里的加可以原创 2012-02-06 17:58:31 · 849 阅读 · 0 评论 -
HDU 4288
线段树每个区间记录该区间内sum[0...4],在区间合并用时注意右区间需要用上左区间的所含元素个数。#include#include#include#define N 100100typedef long long ll;using namespace std;struct Point{ int l,r; int num;//number in the原创 2012-09-16 20:05:27 · 1284 阅读 · 0 评论 -
HDU 4328
单调栈和简单DP#include#include#includeusing namespace std;struct point{ int h; int w;}stack[1005];int n,m;char in[1010];int map[1010][1010];int dp[1010][1010];int sum[1010][1010];int DP原创 2012-09-28 15:44:51 · 774 阅读 · 0 评论 -
zoj 3633
排序+map乱搞题#include#include#include#define N 500100#define Q 50100using namespace std;struct Query{ int l,r,id,ans;}query[Q];bool cmp1(struct Query a,struct Query b){ return a.r>b.r;原创 2012-08-29 14:49:20 · 943 阅读 · 0 评论 -
HDU 4313
这个题有两种做法1.并查集 初始时一条边都不加,将所有边按权值从大到小排序,然后依次判断每一个边两端的顶点是否是均为machine节点,如果是则应删除这条边,否则加入这条边,然后在并查集合并时尽量让根节点为machine节点。#include#include#include#include#include#include#includeusing namesp原创 2012-07-27 14:44:31 · 1231 阅读 · 2 评论 -
HDU 4027 单点更新+“剪枝”
可以看出一个数开方大于等于7次时就一直为1了,利用这点剪枝#include#include#includetypedef long long ll;ll num[100010];struct Tree{ int l,r; ll sum;}tree[400000];void build(int s,int t,int id){ tree[id].l=s;原创 2012-08-10 21:04:56 · 789 阅读 · 0 评论 -
poj 2750
线段树#include#include#include#includeusing namespace std;int n,q;struct node{ int l,r; int sum; int amax,amin; //区间最大、小序列和 int lmax,rmax; //区间最左、右连续最大和 int l原创 2012-07-22 15:00:37 · 1355 阅读 · 0 评论 -
poj 2828
线段树区间存储空位数逆序插入即可#include#include#include#includeusing namespace std;int n;int pos[200001],val[200001],newpos[200001];struct point{ int l,r; int num;}tree[600000];void原创 2012-07-21 17:09:09 · 809 阅读 · 0 评论 -
poj 3368
线段树区间存储最大的频率不习惯写RMQ还是线段树好了...#include#include#include#includeusing namespace std;int n,q;struct node{ int l,r; int amax,lmax,rmax;}tree[300100];int a[100100];void bui原创 2012-07-21 14:48:49 · 1316 阅读 · 0 评论 -
poj 2886
线段树+反素数线段树区间存储未出局的小朋友数(与poj2828类似)#include #include #include using namespace std;const int maxn = 500100;char name[maxn][11];int val[maxn];/* a为反素数表,b为对应的约数个数 */int a[37]={1,2,4,原创 2012-07-21 23:29:50 · 1562 阅读 · 0 评论 -
poj 3264
RMQ模版#include#include#include#includeusing namespace std;int n,a[50010],q;int dp1[50010][17],dp2[50010][17];void RMQ_MIN(){ int i,j; for(i=1;i<=n;i++) dp1[i][0]=a[i]原创 2012-07-20 22:58:05 · 728 阅读 · 0 评论 -
HDU 4263
并查集的应用先算出用红边去构成生成树最多用x1条,那么蓝边最少就用n-1-x1;再算出用蓝边去构成生成树最多用x2条,那么蓝边最多就用x2;然后判断k是否介于之间即可#include#include#define N 1010using namespace std;int c1,c2;int f1[N],f2[N];int n,m,k;void init(){原创 2012-09-15 16:53:26 · 851 阅读 · 0 评论 -
HDU 4262
线段树记录区间中已取走的个数#include#include#include#define N 100100using namespace std;int n;int now;long long ans;int a[N],pos[N];struct Tree{ int l,r,num;}tree[N*3];void build(int s,int t,int id原创 2012-09-15 19:52:43 · 745 阅读 · 0 评论 -
HDU 4351
区间合并的线段树#include#include#include#include#define N 100100#define f(x) ((x)==0?0:((x)%9==0?9:(x)%9))using namespace std;struct Tree{ int l,r; int ls,rs,all,num;}tree[5*N];int val[N],原创 2012-10-20 15:48:32 · 1088 阅读 · 0 评论 -
Codeforces 136 divIID && zoj 3633 && HDU 4358
三道类似的线段树可参见这里的代码http://blog.youkuaiyun.com/struggle_mind/article/details/7931956今天下午把HDU 4358重敲了一遍#include#include#include#include#define N 100100using namespace std;int val[N],a[N],nu原创 2012-09-02 21:57:28 · 1039 阅读 · 0 评论 -
URAL 1992
可持久化链表#include #include #include #include #define N 500010using namespace std;int lehead[N],rehead[N];struct Node{ int val,next;}node[N];int cnt;void addedge(int u,int val,int * lehea原创 2013-10-30 14:57:21 · 1211 阅读 · 0 评论 -
HDU 4325
线段树(成段更新),需要 离线离散化成端更新,查询单点(只要涉及成端更新一定要打懒标记)比赛时队友暴搞过了ORZ原创 2012-07-31 19:37:00 · 1029 阅读 · 0 评论 -
HDU 4267
这棵线段树又写跪了!需要明白(i - a) % k == 0等价与i%k=a%k单点查询#include#include#include#include#include#include#include#include#include#define eps 1e-7#define LL long long#define N 5原创 2012-09-12 20:12:24 · 759 阅读 · 0 评论 -
POJ 3667 Hotel
经典类型,求一块满足条件的最左边的空间。成段更新#include #include using namespace std;const int maxn = 50000 * 3;struct Node{ int left, right; int stat; // 0:区间全为0,1:区间全为1,2:区间有部分为0部分为1 int原创 2012-02-10 14:14:54 · 701 阅读 · 0 评论 -
HDU 4630、BOJ 某题
两道离线线段树。比赛时候没想到。。。。扫描数组,i从1到n,线段树维护从1到i每一个约数(1~50000)的出现的最近位置,线段树存储的是约数的最大值原创 2013-08-01 00:08:16 · 1725 阅读 · 0 评论 -
HDU 3698
线段树优化DP#include#include#define inf ((~(0U))>>1)using namespace std;typedef long long ll;int map[105][5010],c[105][5010];int dp[105][5010];struct Tree{ int l,r,min,lazy;}tree[4*5010];/原创 2012-10-25 16:57:21 · 979 阅读 · 0 评论 -
HDU 1542 Atlantis
线段树+离散化+扫描线和求矩形合并周长思路差不多#include#include#define N 10010using namespace std;struct Tree{ int l,r,cover; //len表示区间【l,r】被占用的总长度 double len;}tree[3*N];struct Line{ double x,y1,y2原创 2012-02-10 12:45:19 · 818 阅读 · 0 评论 -
POJ 1177
线段树+离散化+扫描线可以只扫一遍竖线段(下面代码),也可以横竖都扫一遍(见http://archive.cnblogs.com/a/2197109/)#include#include#define N 10010using namespace std;struct Tree{ int l,r,num,len,cover; //num表示区间【l,r】内线段条数,le原创 2012-02-10 11:32:18 · 922 阅读 · 0 评论 -
HDU 4419
矩形面积并#include#include#define N 20010using namespace std;typedef long long ll;struct Tree{ int l,r,cover[8]; //len表示区间【l,r】被占用的总长度 ll len[8];}tree[5*N];struct Line{ ll x,y1,y2;原创 2012-10-25 14:02:00 · 1077 阅读 · 0 评论 -
poj 1984
带权并查集#include#include#include#includeusing namespace std;int f[40010];int s1[40010],s2[40010]; //s1为水平,s2为竖直int ans[10010];struct Road{ int u,v,c; char dir;}road[40010];struct Que原创 2012-08-03 21:17:06 · 1554 阅读 · 0 评论 -
POJ 1840 Eqs
思路:a1x1^3+ a2x2^3+ a3x3^3 = -(a4x4^3 + a5x5^3)先求出右边能到达的值,对值进行hash,然后左边查询计数,这样比相反的顺序内存少用好多,时间也快不少#include#include#include#include#define inf 20003int Max(int a,int b){ return a>b?a:b;}int M原创 2012-02-18 17:35:24 · 721 阅读 · 0 评论 -
ural 1709
简单并查集#include#includeusing namespace std;int n,d,a;int f[110];char map[110][110];long long sum; //这里sum要用ll,int范围-2147483648--2147483647void init(){ int i,j;原创 2012-07-12 15:19:24 · 824 阅读 · 0 评论 -
poj 2528 Mayor's posters 线段树+离散化
离散化处理要注意+1(看了HH大牛的博客懂的,以前自己的代码是不对的)例如数据:131 101 36 10这样,普通离散化处理 {1 3 6 10}, 然后此程序会操作成点染色,于是结果为2, 但正确答案为 3;HH大牛给出一种离散化方法: 如果相邻数字间距大于1的话,在其中加上任意一个数字,比如加成[1,2,3,6,7,10],然后再做线段树就好了原创 2011-12-06 22:10:24 · 634 阅读 · 0 评论 -
HDU 1394 Minimum Inversion Number
此题利用线段树/树状数组求逆序数。关于逆序数有一个结论:数组循环移位逆序数sum=sum+n-2*in[i]-1,很容易想#include#includeint n;int in[200010];struct Tree{ int s; int t; int sum;}tree[540000];int min(int a,int b){ return a>b?b:a;}原创 2012-02-06 22:56:33 · 666 阅读 · 0 评论 -
HDU 1754 I Hate It(单点更新)
很水的线段树,单点更新(RMQ更快)#include#includeint n;int in[200010];struct Tree{ int s; int t; int max;}tree[540000];int max(int a,int b){ return a>b?a:b;}void build(int s,int t,int id){ tree[id].s=原创 2012-02-06 16:29:57 · 625 阅读 · 0 评论 -
HDU 2795 Billboard线段树
首先把线段树建好,这个题就很简单了。#include#include#includetypedef long long ll;int h,w,n,k;struct Tree{ int s; int t; int max;}tree[540010];void build(int s,int t,int id){ tree[id].s=s; tree[id].t=t;原创 2012-02-07 16:53:45 · 700 阅读 · 0 评论 -
POJ 3468 A Simple Problem with Integers 成段更新
中间乘法溢出了,好纠结(囧).. #include#include#includetypedef long long ll;int in[100000];struct Tree{ int s; int t; ll sum; int add;}tree[270010];void build(int s,int t,int id){ tree[id].s=s; tr原创 2012-02-07 15:33:47 · 640 阅读 · 0 评论 -
POJ 2777 Count Color
和poj2528类似,不过不用离散化,也可以用位运算加速(因为颜色总共不过30种)#include#include#includebool visit[35];int ans;struct Tree{ int s; int t; int c;}tree[270010];void build(int s,int t,int id){ tree[id].s=s; tre原创 2012-02-07 11:56:49 · 663 阅读 · 0 评论 -
POJ 2796 Feel Good 单调栈
最近做这方面的题很多,感觉单调栈很是神奇,通过维护一个单调不减的栈,遇到小于栈顶的栈顶元素便出栈,此时跟新结果。这个比RMQ的ST算法要快很多,ST算法要枚举每一个区间(没想到其他做法,可能要dp,反正不会)。这个题关键在于给每一个点找一个最长子序列,使其最小值为其本身,这样扫一遍得到结果。而单调栈正好可以解决这个问题。(这个题大家注意要用long long我被int卡死,干脆全换long原创 2012-01-21 16:10:49 · 1780 阅读 · 0 评论 -
POJ 2082 Terrible Sets 单调栈的应用
题目条件叙述挺恶心的,其实表达意思挺简单的。就是给你几个矩形(依次在x轴上排开),问你能够组成的最大矩形面积。本题采用一个栈作为存储数据结构,当前读入的矩形的高度如果大于栈顶矩形的高度的话直接进栈,否则依次出栈计算跟新最大面积,直到某一刻栈顶的高度小于当前读入的矩形的高度,进栈,这样把所以矩形都读入后在扫一遍栈跟新最大面积即可。#include#include#include#inc原创 2012-01-21 01:09:19 · 1766 阅读 · 0 评论 -
HDU 3234 Exclusive-OR 扩展并查集
这个题坑了我两小时,查了半天,最后发现自己一直都弄错了运算符的优先性。val[p]^val[q]!=v是错的,应该写成((val[p]^val[q])!=v),异或运算符优先性比关系运算符==低#include#include#includeusing namespace std;int root[20010],val[20010],temp[20],xor[20],roo[20];in原创 2011-12-13 18:53:28 · 973 阅读 · 0 评论 -
POJ 1200 Crazy Search hash水题
好像ELFhash过不了啊,换了个hash函数过了#include#include#include#define maxn 16000000 char s[maxn];int a[1000];bool vis[1000];int hash[maxn]; int main(){ int N,NC,num=0,len,i,cnt=0,sum=0,j; scanf("%d%d原创 2012-02-08 17:12:46 · 789 阅读 · 0 评论 -
HDU 3397 Sequence operation
重点是求给定区间的最长连续1,这个和poj 3667hotel思路相似#include using namespace std;int in[100010]; struct Node{ int left, right,sum; int stat; // 0:区间全为0,1:区间全为1,2:区间有部分为0部分为1 int lmax, r原创 2012-02-10 16:34:45 · 724 阅读 · 0 评论 -
zoj 3453 Cupid's Sweet Bullet
简单线段树,成段更新#include #define con 100100using namespace std;int em[con],l[con],r[con],n;struct Tree{ int s; int t; int max; int add;}tree[270010];int max(int a,int b){ return a>b?a:b;}void原创 2012-02-24 00:08:52 · 1133 阅读 · 0 评论 -
bnuoj 14368 Lisy的密码
树状数组的简单应用求逆序数需要离线树状数组,正反2次求#include#include#includeusing namespace std;int c[100100],a[50010];int l[50010],r[50010]; //记录每一个改变位置的改变对于此位置以左和以右的逆序数的影响int maxl;int n,m;struct point{ i原创 2012-07-08 17:41:14 · 972 阅读 · 0 评论