随笔分类 -  数据结构

摘要:splay 练手用;杭电的oj要手动开栈;#include#pragma comment(linker, "/STACK:102400000,102400000")#include#include#define inf 999999#define maxn 1500009#define lch(rt) son[rt][0]#define rch(rt) son[rt][1]using namespace std;int son[maxn][2],fa[maxn];int val[maxn],size[maxn],flg[maxn];int cnt,root;int num[ 阅读全文
posted @ 2014-03-14 15:12 Yours1103 阅读(205) 评论(0) 推荐(0)
摘要:splay#include#include#include#include#define maxn 300009#define lch(rt) son[rt][0]#define rch(rt) son[rt][1]using namespace std;int son[maxn][2],fa[maxn],size[maxn],val[maxn],st[maxn];int root,cnt;int num[maxn],flg[maxn];int n,m;void push_up(int rt){ size[rt]=size[lch(rt)]+size[rch(rt)]+1;}void p... 阅读全文
posted @ 2014-03-13 21:53 Yours1103 阅读(162) 评论(0) 推荐(0)
摘要:一道区间更新、查询的题;但是线段树不能做插入;后来才知道用splay;splay用来做区间查询的话,先将l-1旋转到根节点,然后把r+1旋转到根节点的右节点;这样的话,根节点的右节点的左子树就是我们要的区间;我的代码是网上大神的代码改了一下过来的,存着做模板;#include#include#include#define maxn 2000009#define lch(rt) son[rt][0]#define rch(rt) son[rt][1]using namespace std;int son[maxn][2],fa[maxn],size[maxn],val[maxn],st[maxn 阅读全文
posted @ 2014-03-04 13:42 Yours1103 阅读(198) 评论(0) 推荐(0)
摘要:这道题目的意思是对于每个要删除的数字,向前或向后找到一块连续的数字,而它是其中最小的;很容易看出对于所有要先删除的数字要从大到小删除;然后对于每个要删除的字母,要找到比他小的,但是在原数列中又靠它最近的数字;这样的话,很直观最多只能用lg n的复杂度来处理这个问题;可以用二分查找,也可以用set来代替;考虑到前面删除的一些数字不能计算进去,还要一个快速计算区间和的算法,用树状数组和线段树都可以;不过看到tags,上面写着还可以用dsu(disjoint set union)并查集来做;感觉挺神奇的,想到了之后再补上!#include#include#include#include#define 阅读全文
posted @ 2014-02-25 13:44 Yours1103 阅读(267) 评论(0) 推荐(0)
摘要:本题的主要算法就是区间更新和区间求和;可以用线段树和树状数组来做;感觉线段树写的太麻烦了,看到官方题解上说可以用树状数组做,觉得很神奇,以前用过的树状数组都是单点维护,区间求和的;其实树状数组还可以区间维护,单点求值;和区间维护,区间求和的;详情请见博客。#include#include#include#include#define maxn 4000010#define ll long longusing namespace std;ll a[2][maxn];ll b[2][maxn];void add_a(int flag,int x,ll value){ while(x>0) . 阅读全文
posted @ 2014-02-23 21:29 Yours1103 阅读(245) 评论(0) 推荐(0)
摘要:这个题我想到要用kmp找到循环节;但是后面的我就不会做了;看到题解才知道是字符串的最小表示;#include#include#include#define maxn 100005using namespace std; char s[maxn*2];int next[maxn]; void kmp(int n){ int j=0; for(int i=2;i0&&s[i]!=s[j+1])j=next[j]; if(s[i]==s[j+1])++j; next[i]=j; }} void MinimumRepresentation(int n){ ... 阅读全文
posted @ 2013-12-11 22:41 Yours1103 阅读(158) 评论(0) 推荐(0)
摘要:因为每个元素都是移动到比它小1位的元素的后面;这样的话以后的一定就可以把他们两个打包;所以用这种方法最多扫一遍就可以了;但是最小的那个数要不要移动呢?如果最小的数后面的数都是升序的,那么一直扫到最小的那个数就行了;不然的话要完整的扫一遍;这个地方我没想清楚,WA的好惨,最后还是看到斌哥的代码才恍然大悟的;#include#include#define maxn 100005using namespace std;int n,t,m;int num[maxn],f[maxn],r[maxn],cnt[maxn]; bool cmp(const int &x,const int & 阅读全文
posted @ 2013-12-11 22:38 Yours1103 阅读(158) 评论(0) 推荐(0)
摘要:用set写真是轻松愉快;#include#include#include#includeusing namespace std;setst;int ans;int main(){ int n,x; st.insert(-99999999); st.insert(99999999); scanf("%d",&n); for(int i=0; i0) { ans+=y; st.insert(x); } } } printf("%d\n",a... 阅读全文
posted @ 2013-12-05 18:14 Yours1103 阅读(320) 评论(0) 推荐(0)
摘要:单点更新,区间求最大值的题;可以使用树状数组和线段树;#include#include#include#define maxn 2000009#define ll long longusing namespace std;int m,n=0;ll ma[maxn],d[maxn];void insert(int w,ll x){ d[w]=x; while(w=l) { ret=max(ret,ma[r]); r-=r&-r; } else r--; } return ret;}cha... 阅读全文
posted @ 2013-12-03 15:28 Yours1103 阅读(136) 评论(0) 推荐(0)
摘要:这是一个线段树的题目;我记得一个月前在cf上也做过一个类似的题目; 1 #include 2 #include 3 #include 4 #define maxn 100010 5 #define bon 1000010 6 using namespace std; 7 int cover[bon=0)21 {22 cover[rt=0) return cover[rt];30 int mid=(l+r)>>1;31 pushdown(rt);32 if(x=r)39 {40 cover[rt]=i;41 ... 阅读全文
posted @ 2013-11-15 23:02 Yours1103 阅读(631) 评论(0) 推荐(0)
摘要:一个简单的搜索;反正树的结构不会变,只需要把节点的名称换一下就行;可惜比赛的时候思路不清晰; 1 #include 2 #define maxn 5050 3 #include 4 #include 5 #include 6 using namespace std; 7 int age[maxn]; 8 int biao[maxn]; 9 bool vis[maxn];10 vectorve[maxn],pa[maxn];11 char s[10];12 int ans;13 void dfs(int x,int v)14 {15 vis[x]=1;16 pa[v].push_... 阅读全文
posted @ 2013-11-15 16:21 Yours1103 阅读(242) 评论(0) 推荐(0)
摘要:求最大的公共前缀;用后缀数组做;其实暴力也可以过; 1 #include 2 #include 3 #include 4 #define maxn 2009 5 using namespace std; 6 7 int s[maxn]; 8 int sa[maxn],t[maxn],t2[maxn],c[maxn],n; 9 10 void build_sa(int m) 11 { 12 int *x=t,*y=t2; 13 for(int i=0; i=0; i--)sa[--c[x[i]]]=i; 17 for(int k=1; k=k)y[p... 阅读全文
posted @ 2013-11-13 23:14 Yours1103 阅读(207) 评论(0) 推荐(0)
摘要:set的利用; 1 #include 2 #include 3 #include 4 #define maxn 100009 5 using namespace std; 6 7 struct node 8 { 9 int w,h;10 bool operator s;18 multiset::iterator it;19 int main()20 {21 int n,t;22 scanf("%d",&t);23 while(t--)24 {25 scanf("%d",&n);26 s.clear();27 ... 阅读全文
posted @ 2013-11-12 18:59 Yours1103 阅读(153) 评论(0) 推荐(0)
摘要:一个很不错的题;刚刚看到这个题目就感觉要用线段树或者树状数组,但是有感觉有点不同;敲了一发简单的线段树之后果断的T了;网上一搜题解,发现要用55颗线段树或者树状数组;一共有k种树,然后每种树根据他们%k的余数的不同又分成好几颗;然后最后统计的时候只要对每个节点统计这k种树种的信息就行; 1 #include 2 #include 3 #define maxn 50005 4 using namespace std; 5 6 int d[100][maxn],num[maxn]; 7 int n,q; 8 void insert(int k,int p,int v) 9 {10 whi... 阅读全文
posted @ 2013-11-12 16:57 Yours1103 阅读(188) 评论(0) 推荐(0)
摘要:简单的线段树的题;有两种方法写这个题,目前用的熟是这种慢点的;不过不知道怎么老是T;感觉网上A过的人的时间度都好小,但他们都是用数组实现的难道是指针比数组慢?好吧,以后多用数组写写吧!超时的代码: 1 #include 2 #include 3 #include 4 #define maxn 1000009 5 using namespace std; 6 7 struct node 8 { 9 int l,r; 10 int ma,mi,sum; 11 int ad,st; 12 bool flag1,flag2; 13 node ... 阅读全文
posted @ 2013-11-02 17:10 Yours1103 阅读(189) 评论(0) 推荐(0)
摘要:又是一道线段树区间更新的题; 1 #include 2 #include 3 #include 4 #define ll long long 5 #define maxn 500005 6 using namespace std; 7 ll sum[maxn]; 8 struct tree 9 { 10 int l,r; 11 int ml,mr; 12 int pre,suf; 13 tree *left,*right; 14 } tr[maxn*2]; 15 16 int trcount; 17 18 void build(tree *... 阅读全文
posted @ 2013-11-02 12:05 Yours1103 阅读(243) 评论(0) 推荐(0)
摘要:splay的题;学习白书上和网上的代码敲的; 1 #include 2 #include 3 #include 4 #include 5 using namespace std; 6 int n,m; 7 struct node 8 { 9 node *ch[2]; 10 int s,v; 11 int flip; 12 node(int v):v(v) 13 { 14 ch[1]=ch[0]=NULL; 15 s=1; 16 flip=0; 17 } 18 voi... 阅读全文
posted @ 2013-11-01 18:58 Yours1103 阅读(194) 评论(0) 推荐(0)
摘要:用可重集;首先按照x排好序,然后只要找到下界,插入,然后把y坐标大于它的都删掉就行; 1 #include 2 #include 3 using namespace std; 4 5 struct node 6 { 7 int a,b; 8 bool operators;16 multiset::iterator it;17 18 int main()19 {20 int t,n,ca=1;21 node p;22 scanf("%d",&t);23 while(t--)24 {25 s.clear();26 ... 阅读全文
posted @ 2013-10-31 22:42 Yours1103 阅读(151) 评论(0) 推荐(0)
摘要:基于hash的LCP算法; 1 #include 2 #include 3 #include 4 #define maxn 40010 5 using namespace std; 6 7 const int x=123; 8 int n,m,pos; 9 unsigned long long h[maxn],xp[maxn],hash[maxn];10 int rank[maxn];11 12 bool cmp(const int &a,const int &b)13 {14 return hash[a]=m)pos=max(pos,rank[i]);31 }32 ... 阅读全文
posted @ 2013-10-31 22:18 Yours1103 阅读(254) 评论(0) 推荐(0)
摘要:花了一个半小时的时间,终于把这个题目给A了;知道用后缀数组后,这个题目其实不难;就一个二分;用白书当模板其实还挺不错的! 1 #include 2 #include 3 #include 4 #define maxn 110009 5 using namespace std; 6 7 int s[maxn]; 8 int sa[maxn],t[maxn],t2[maxn],c[maxn],n; 9 10 void build_sa(int m) 11 { 12 int *x=t,*y=t2; 13 for(int i=0; i=0; i--)sa[--c[... 阅读全文
posted @ 2013-10-31 17:52 Yours1103 阅读(569) 评论(0) 推荐(0)