【数据结构】
欣君
追寻那如樱花般的绚烂
展开
-
51nod 1287 加农炮
二分+线段树的经典题目 #include using namespace std; int num[100000]; struct node { int l,r; long long nsum; }segtree[300000]; void build(int i,int l,int r) { segtree[i].l=l; segtree[i].r=r; if(l==r) {原创 2016-11-06 14:28:08 · 237 阅读 · 0 评论 -
51nod 1681 公共祖先
主席树,让我有点懵逼。。。 //#include #include #include using namespace std; void read(int&a){ char ch;while(!((ch=getchar())>='0')&&(ch<='9')); a=ch-'0';while(((ch=getchar())>='0')&&(ch<='9'))a*=10,a+=c原创 2017-07-18 16:55:06 · 316 阅读 · 0 评论 -
51nod 1461 稳定桌
用线段树查询区间k小和。 #include using namespace std; const int MAXN=100100; int cnt[MAXN]; struct Leg { int l,d; }arr[MAXN]; bool cmp(Leg l1,Leg l2) { return l1.l>l2.l; } struct node { long long c,v; }原创 2017-07-15 16:51:27 · 331 阅读 · 0 评论 -
51nod 1349 最大值
单调栈瞎搞一下就好了 //#include #include #include #include #include using namespace std; const int MAXN=100100; long long a[MAXN],bef[MAXN],aft[MAXN],ans[MAXN],stk[MAXN]; int main() { long long n,i,k,cnt,q;原创 2017-07-05 16:14:25 · 365 阅读 · 2 评论 -
51nod 1962 区间计数
#include using namespace std; const int MAXN=400400; pair p[MAXN],q[MAXN]; int a[MAXN],b[MAXN],ra[MAXN],rb[MAXN]; int ins(pair x,pair y)//计算区间并的大小 { if(x.second>y.second) swap(x,y); if(x.second转载 2017-07-12 15:47:30 · 312 阅读 · 0 评论 -
51nod 1562 玻璃切割
之前连续好几天没怎么睡,还好没得道成仙。。。ddl是第一生产力。。。 找了道水题做下。 倒序处理所有答案,再输出。 用可以用并查集进行合并区间操作(一开始想写伪链表的,发现好像不行)。不断更新横纵最大值即可。 #include using namespace std; void read(int &a) { char ch;while(!((ch=getchar())>='0')原创 2017-05-03 22:22:14 · 637 阅读 · 0 评论 -
51nod 1766 树上的最远点对
线段树套LCA。。。写了近200行 对于区间[a,b]和区间[c,d]上各选一点的最大长度,必定等于区间[a,b]内最远点对中的某一点,与区间[c,d]内最远点对中的某一点,这两点的距离。因为有这个性质,就可以在线段树上进行查询了。注意线段树中的合并merge操作,与求答案时的merge操作,有些不同。 #include using namespace std; void read(int原创 2017-02-26 16:23:44 · 424 阅读 · 0 评论 -
51nod 1394 差和问题
每次修改,都能直接更新答案。数据可以用树状数组或线段树维护。 #include using namespace std; const int MAXN=200100; char op[MAXN]; int discnum; long long disc[MAXN],v[MAXN]; long long c[2][2][MAXN],a[MAXN]; void update(int num,int原创 2017-02-12 16:01:43 · 251 阅读 · 0 评论 -
51nod 1463 找朋友
离线+线段树 将询问按右端点排序。这样对于(i,j),j必定在当前询问范围内。可以将a[i]+a[j]累积到i上,那样就变成了求区间最大值。 #include using namespace std; void read(int&a){ char ch;while(!((ch=getchar())>='0')&&(ch<='9')); a=ch-'0';while(((ch原创 2017-02-19 23:42:08 · 469 阅读 · 0 评论 -
51nod 1282 时钟
哈希+map,不会哈希的我好弱鸡。。。 #include using namespace std; const int seed=133331; int n,m,p; int a[550][550],b[550][550],minid[550]; map mp; int getminid(int *c) { int i=0,j=1,k=0,tmp; while(i<m&&j<m&&k<转载 2016-11-07 22:37:45 · 242 阅读 · 0 评论 -
HDU 6041 I Curse Myself
由于每条边最多只在一个环上,因此可以将环上的边权值,构成一个集合。问题就变成了,从若干个集合中,每个集合取一个数,计算K大的总和。 一次性考虑所有集合不太容易,可以将集合依次合并过去。那样复杂度就是O(KM)。 #include using namespace std; const int MAXN=1010; const int MAXM=4020; struct Edge { int原创 2017-07-26 14:53:17 · 911 阅读 · 0 评论