HDU 1166 敌兵布阵

单调更新区间查询和

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXN = ;
const int INF = 0x3f3f3f3f;
struct node
{
int l,r;
int sum;
}tree[MAXN * ];
int src[MAXN]; void build(int id,int l,int r)
{
tree[id].l = l;
tree[id].r = r;
if (l == r)
{
tree[id].sum = src[l];
return;
}
int mid = (l + r) / ;
build(id * ,l,mid);
build(id * + ,mid + ,r);
tree[id].sum = tree[id * ].sum + tree[id * + ].sum;
} void update(int id,int pos,int val)
{
if (tree[id].l == pos && tree[id].r == pos)
{
tree[id].sum += val;
return;
}
int mid = (tree[id].l + tree[id].r) / ;
if (pos <= mid) update(id * ,pos,val);
else update(id * + ,pos,val);
tree[id].sum = tree[id * ].sum + tree[id * + ].sum;
} int query(int id,int l,int r)
{
if (tree[id].l >= l && tree[id].r <= r)
{
return tree[id].sum;
}
int mid = (tree[id].l + tree[id].r) / ;
if (l > mid) return query(id * + ,l,r);
else if (r <= mid) return query(id * ,l,r);
else
{
return query(id * ,l,mid) + query(id * + ,mid + ,r);
}
} int main()
{
int T,kase = ;
scanf("%d",&T);
while (T--)
{
int N;
scanf("%d",&N);
for (int i = ; i <= N ; i++) scanf("%d",&src[i]);
build(,,N);
printf("Case %d:\n",kase++);
char op[];
while(scanf("%s",op) != EOF)
{
if (op[] == 'E') break;
if (op[] == 'Q')
{
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",query(,l,r));
}
if (op[] == 'A')
{
int x,val;
scanf("%d%d",&x,&val);
update(,x,val);
}
if(op[] == 'S')
{
int x,val;
scanf("%d%d",&x,&val);
update(,x,-val);
}
}
}
return ;
}

HDU 1754 I Hate It

单点更新区间查询最值

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXN = ;
const int INF = 0x3f3f3f3f;
struct node
{
int l,r;
int val;
}tree[MAXN * ];
int src[MAXN]; void build(int id,int l,int r)
{
tree[id].l = l;
tree[id].r = r;
if (l == r)
{
tree[id].val = src[l];
return;
}
int mid = (l + r) / ;
build(id * ,l,mid);
build(id * + ,mid + ,r);
tree[id].val = max(tree[id * ].val,tree[id * + ].val);
} void update(int id,int pos,int val)
{
if (tree[id].l == pos && tree[id].r == pos)
{
tree[id].val = val;
return;
}
int mid = (tree[id].l + tree[id].r) / ;
if (pos <= mid) update(id * ,pos,val);
else update(id * + ,pos,val);
tree[id].val = max(tree[id * ].val,tree[id * + ].val);
} int query(int id,int l,int r)
{
if (tree[id].l >= l && tree[id].r <= r)
{
return tree[id].val;
}
int mid = (tree[id].l + tree[id].r) / ;
if (l > mid) return query(id * + ,l,r);
else if (r <= mid) return query(id * ,l,r);
else
{
return max(query(id * ,l,mid) ,query(id * + ,mid + ,r));
}
} int main()
{
int N,Q;
while (scanf("%d%d",&N,&Q) != EOF)
{
for (int i = ; i <= N; i++) scanf("%d",&src[i]);
build(,,N);
while (Q--)
{
char op[];
scanf("%s",op);
if (op[] == 'Q')
{
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",query(,l,r));
}
else
{
int x,val;
scanf("%d%d",&x,&val);
update(,x,val);
}
}
}
return ;
}

POJ 3468 A Simple Problem with Integers

区间更新区间求和。

这里就要涉及到懒操作。注意的是lazy被更新的区间一定是当前的区间和已经更新完

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXN = ;
const int INF = 0x3f3f3f3f;
struct node
{
int l,r;
LL lazy,sum;
}tree[MAXN * ];
LL src[MAXN]; void build(int id,int l,int r)
{
tree[id].l = l;
tree[id].r = r;
tree[id].lazy = ;
if (l == r)
{
tree[id].sum = src[l];
return;
}
int mid = (l + r) / ;
build(id * ,l,mid);
build(id * + ,mid +,r);
tree[id].sum = tree[id * ].sum + tree[id * + ].sum;
} void push_down(int id)
{
if (tree[id].lazy == ) return;
tree[id * ].sum += (tree[id * ].r - tree[id * ].l + ) * tree[id].lazy;
tree[id * ].lazy += tree[id].lazy;
tree[id * + ].sum += (tree[id * + ].r - tree[id * + ].l + ) * tree[id].lazy;
tree[id * + ].lazy += tree[id].lazy;
tree[id].lazy = ;
} void update(int id,int l,int r,LL val)
{
if (tree[id].l >= l && tree[id].r <= r)
{
tree[id].lazy += val;
tree[id].sum += val * (r - l + );
return;
}
push_down(id);
int mid = (tree[id].r + tree[id].l) / ;
if (l > mid) update(id * + ,l,r,val);
else if (r <= mid) update(id * ,l,r,val);
else
{
update(id * ,l,mid,val);
update(id * + ,mid + ,r,val);
}
tree[id].sum = tree[id * ].sum + tree[id * + ].sum;
} LL query(int id,int l,int r)
{
if (tree[id].l >= l && tree[id].r <= r)
{
return tree[id].sum;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) / ;
if (l > mid) return query(id * + ,l,r);
else if (r <= mid) return query(id * ,l,r);
else
{
return query(id * ,l,mid) + query(id * + ,mid + ,r);
}
} int main()
{
int N,Q;
while (scanf("%d%d",&N,&Q) != EOF)
{
for (int i = ; i <= N ; i++) scanf("%I64d",&src[i]);
build(,,N);
char op[];
while (Q--)
{
scanf("%s",op);
if (op[] == 'Q')
{
int l,r;
scanf("%d%d",&l,&r);
printf("%I64d\n",query(,l,r));
}
else
{
int l,r;
LL val;
scanf("%d%d%I64d",&l,&r,&val);
update(,l,r,val);
}
}
}
return ;
}

POJ 2528 Mayor's posters

区间更新为一个值。然后统计有哪些数出现过

注意需要离散化,且不能随便离散化。

线段树是点操作。这里对长度为1的段进行操作。也就是将一个长度为1的段视作一个点,举个例子

区间为 1-10,1--4,5 -- 10

区间为 1--10,1--4,6-10;

一般的离散化是变成了这样 1离散为1,4离散为2,5离散为3,10离散为4

区间都变成了1-4,1--2,3 -- 4;

显然上面2中答案是不一样的。随便离散是WA的。第一个答案是2,第二个答案是3

那么如何改,方案是如果两个相邻的点差值大于1,那么中间就插入一个点。

那么按照这种离散上面变成了有6个点1,3,4,5,9,10,离散成了1-6,1-3,4-6 答案为2

和第二组问题 变成这样几个点1 3 4 5 6 9 10 离散成了 1--7,1--3,5--7答案为3

代码

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXN = ;
map<int,int>mp,res;
struct point
{
int l,r;
int idx;
}src[MAXN];
struct node
{
int l,r;
int val;
bool flag;
}tree[MAXN * ];
int ori[MAXN * ],newdata[MAXN * ]; void build(int id,int l,int r)
{
tree[id].l = newdata[l];
tree[id].r = newdata[r];
tree[id].val = -;
tree[id].flag = false;
if (l == r) return;
int mid = (l + r) / ;
build(id * ,l,mid);
build(id * + ,mid + ,r);
} void push_down(int id)
{
if (tree[id].flag)
{
tree[id * ].flag = tree[id * + ].flag = true;
tree[id * ].val = tree[id * + ].val = tree[id].val;
tree[id].flag = false;
}
} void update(int id,int l,int r,int val)
{
if (r < tree[id].l || l > tree[id].r) return;
if (tree[id].l >= l && tree[id].r <= r)
{
tree[id].val = val;
tree[id].flag = true;
return;
}
push_down(id);
/*int mid = (tree[id].l + tree[id].r) / 2;
if (l > mid) update(id * 2 + 1,l,r,val);
else if (r <= mid) update(id * 2,l,r,val);
else
{
update(id * 2 ,l,mid,val);
update(id * 2 + 1,mid + 1,r,val);
}*/
update(id * ,l,r,val);
update(id * + ,l,r,val);
} void query(int id,int l,int r,int &ret)
{
if (tree[id].l == tree[id].r)
{
if (mp[tree[id].val] == && tree[id].val != -)
{
ret++;
// printf("%d\n",tree[id].val);
mp[tree[id].val] = ;
}
return;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) / ;
query(id * ,l,mid,ret);
query(id * + ,mid + ,r,ret);
} int main()
{
int T;
scanf("%d",&T);
while (T--)
{
mp.clear();
res.clear();
int N;
scanf("%d",&N);
int cas = ;
for (int i = ; i <= N ; i++)
{
scanf("%d%d",&src[i].l,&src[i].r);
src[i].idx = i;
ori[++cas] = src[i].l;
ori[++cas] = src[i].r;
}
sort(ori + ,ori + + cas);
int leap = ;
ori[] = -;
for (int i = ; i <= cas ; i++)
{
if (ori[i] != ori[i - ])
ori[++leap] = ori[i];
}
cas = ;
newdata[++cas] = ori[];
for (int i = ; i <= leap ; i++)
{
if (ori[i] > ori[i - ] + )
{
newdata[++cas] = ori[i] - ;
newdata[++cas] = ori[i];
}
else
{
newdata[++cas] = ori[i];
}
}
// printf("%d\n",cas);
//for (int i = 1 ; i <= cas ; i++)
// printf("%d ",newdata[i]); putchar('\n');
build(,,cas);
for (int i = ; i <= N ; i++)
{
update(,src[i].l,src[i].r,src[i].idx);
}
int ret = ;
query(,,cas,ret);
printf("%d\n",ret);
}
return ;
}

hdu 1698 Just a Hook

记得题意是如果一个区间值全部相等,那么权就是这个区间的长度乘以这个值,最开始全都是1

用一个sta记录这个区间是不是所值都相等然后做

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXN = ;
const int INF = 0x3f3f3f3f;
struct node
{
int l,r;
bool sta;
int val;
bool flag;
}tree[MAXN * ];
int L; void build(int id,int l,int r)
{
tree[id].l = l;
tree[id].r = r;
tree[id].val = ;
tree[id].flag = false;
tree[id].sta = true;
if (l == r) return;
int mid = (l + r) / ;
build(id * ,l,mid);
build(id * + ,mid + ,r);
} void push_down(int id)
{
if (tree[id].flag)
{
tree[id * ].val = tree[id * + ].val = tree[id].val;
tree[id * ].flag = true;
tree[id * + ].flag = true;
tree[id].flag = false;
tree[id].sta = true;
tree[id * ].sta = true;
tree[id * + ].sta = true;
}
} void push_up(int id)
{
if (tree[id * ].sta == true && tree[id * + ].sta == true)
{
if (tree[id * ].val == tree[id * + ].val)
{
tree[id].val = tree[id * + ].val;
tree[id].sta = true;
}
else tree[id].sta = false;
}
else tree[id].sta = false;
} void update(int id,int l,int r,int val)
{
if (tree[id].l >= l && tree[id].r <= r)
{
tree[id].flag = true;
tree[id].val = val;
tree[id].sta = true;
return;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) / ;
if (l > mid) update(id * + ,l,r,val);
else if (r <= mid) update(id * ,l,r,val);
else
{
update(id * ,l,mid,val);
update(id * + ,mid + ,r,val);
}
push_up(id);
} int query(int id,int l,int r)
{
if (tree[id].l >= l && tree[id].r <= r)
{
if (tree[id].sta == true)
{
// printf("%d %d %d\n",tree[id].l,tree[id].r,tree[id].val);
return tree[id].val * (tree[id].r - tree[id].l + );
}
}
push_down(id);
int mid = (tree[id].l + tree[id].r) / ;
if (l > mid) return query(id * + ,l,r);
else if (r <= mid) return query(id * ,l,r);
else
{
return query(id * ,l,mid) + query(id * + ,mid + ,r);
}
} int main()
{
int T,kase = ;
scanf("%d",&T);
while (T--)
{
scanf("%d",&L);
build(,,L);
int Q;
scanf("%d",&Q);
while (Q--)
{
int l,r,val;
scanf("%d%d%d",&l,&r,&val);
update(,l,r,val);
//printf("%d %d %d\n",l,r,val);
}
printf("Case %d: The total value of the hook is %d.\n",kase++,query(,,L));
}
return ;
}

ZOJ 1610 Count the Colors

只有一次查询。可以直接暴力出来修改后最后每个点的颜色。然后扫一遍

我第一次的做法不知道为何就是老WA。求好心人告知。

下面是参照别人A的代码

结构体的COL表示染了什么颜色

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXN = ;
struct node
{
int l,r,col;
}tree[MAXN * ];
int cnt[MAXN],col[MAXN],N; void build(int id,int l,int r)
{
tree[id].l = l;
tree[id].r = r;
tree[id].col = -;
if (l == r) return;
int mid = (l + r) / ;
build(id * ,l,mid);
build(id * + ,mid + ,r);
} void push_down(int id)
{
if (tree[id].col != -)
{
tree[id * ].col = tree[id * + ].col = tree[id].col;
tree[id].col = -;
}
} void update(int id,int l,int r,int val)
{
if (tree[id].l >= l && tree[id].r <= r)
{
tree[id].col = val;
//printf("%d %d %d\n",tree[id].l,tree[id].r,tree[id].col);
return;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) / ;
if (l > mid) update(id * + ,l,r,val);
else if (r <= mid) update(id * ,l,r,val);
else
{
update(id * ,l,mid,val);
update(id * + ,mid + ,r,val);
}
} void query(int id,int l,int r)
{
if (tree[id].l >= l && tree[id].r <= r)
{
//printf("%d\n",tree[id].col);
if (tree[id].col != -)
{
//printf("%d\n",tree[id].col);
for (int i = tree[id].l ; i <= tree[id].r ; i++)
col[i] = tree[id].col;
return;
}
}
push_down(id);
if (l == r) return;
int mid = (tree[id].l + tree[id].r ) / ;
if (l > mid) query(id * + ,l,r);
else if (r <= mid) query(id * ,l,r);
else
{
query(id * ,l,mid);
query(id * + ,mid + ,r);
}
} int main()
{
while (scanf("%d",&N) != EOF)
{
memset(cnt,,sizeof(cnt));
build(,,);
for (int i = ; i <= N ; i++)
{
int l,r,val;
scanf("%d%d%d",&l,&r,&val);
update(,l + ,r,val);
}
memset(col,-,sizeof(col));
query(,,);
int pre = -;
for (int i = ; i <= ; i++)
{
if (col[i] == -)
{
pre = -;
continue;
}
if (pre != col[i])
{
cnt[col[i]]++;
pre = col[i];
}
}
for (int i = ; i <= ; i++)
{
if (cnt[i]) printf("%d %d\n",i,cnt[i]);
}
puts("");
}
return ;
}

下面是我自己WA的代码在查询中就更新出答案不知道那里有问题

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXN = ;
const int INF = 0x3f3f3f3f;
struct node
{
int l,r;
bool flag,sta;
int val;
}tree[MAXN * ];
int N;
int cnt[MAXN]; void build(int id,int l,int r)
{
tree[id].l = l;
tree[id].r = r;
tree[id].val = -;
tree[id].flag = false;
tree[id].sta = true;
if (l == r) return;
int mid = (l + r) / ;
build(id * ,l,mid);
build(id * + ,mid + ,r);
} void push_down(int id)
{
if (tree[id].flag)
{
tree[id * ].val = tree[id * + ].val = tree[id].val;
tree[id * ].flag = true;
tree[id * + ].flag = true;
tree[id].flag = false;
tree[id].sta = true;
tree[id * ].sta = true;
tree[id * + ].sta = true;
}
} void push_up(int id)
{
if (tree[id * ].sta == true && tree[id * + ].sta == true)
{
if (tree[id * ].val == tree[id * + ].val)
{
tree[id].val = tree[id * + ].val;
tree[id].sta = true;
}
else tree[id].sta = false;
}
else tree[id].sta = false;
} void update(int id,int l,int r,int val)
{
if (tree[id].l >= l && tree[id].r <= r)
{
tree[id].flag = true;
tree[id].val = val;
tree[id].sta = true;
return;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) / ;
if (l > mid) update(id * + ,l,r,val);
else if (r <= mid) update(id * ,l,r,val);
else
{
update(id * ,l,mid,val);
update(id * + ,mid + ,r,val);
}
push_up(id);
} void query(int id,int l,int r)
{
if (tree[id].l >= l && tree[id].r <= r)
{
if (tree[id].sta == true)
{
if (tree[id].val != -)
{
cnt[tree[id].val]++;
//a printf("%d\n",tree[id].val);
}
return;
}
}
push_down(id);
int mid = (tree[id].l + tree[id].r) / ;
if (l > mid) query(id * + ,l,r);
else if (r <= mid) query(id * ,l,r);
else
{
query(id * ,l,mid);
query(id * + ,mid + ,r);
}
} int main()
{
//freopen("sample.txt","r",stdin);
while (scanf("%d",&N) != EOF)
{
build(,,);
for (int i = ; i <= N ; i++)
{
int l,r,val;
scanf("%d%d%d",&l,&r,&val);
if (l > r) swap(l,r);
if (l == r) continue;
update(,l + ,r,val);
}
memset(cnt,,sizeof(cnt));
query(,,);
for (int i = ; i <= ; i++)
{
if (cnt[i] == ) continue;
printf("%d %d\n",i,cnt[i]);
}
puts("");
}
return ;
}

POJ 3264 Balanced Lineup

查询区间最大最小值。

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXN = ;
struct node
{
int l,r,MIN,MAX;
}tree[MAXN * ];
int src[MAXN],N; void build(int id,int l,int r)
{
tree[id].l = l;
tree[id].r = r;
if (l == r)
{
tree[id].MIN = tree[id].MAX = src[l];
return;
}
int mid = (l + r) / ;
build(id * ,l,mid);
build(id * + ,mid + ,r);
tree[id].MIN = min(tree[id * ].MIN,tree[id * + ].MIN);
tree[id].MAX = max(tree[id * ].MAX,tree[id * + ].MAX);
} int querymax(int id,int l,int r)
{
if (tree[id].l >= l && tree[id].r <= r)
{
return tree[id].MAX;
}
int mid = (tree[id].l + tree[id].r) / ;
if (l > mid) return querymax(id * + ,l,r);
else if (r <= mid) return querymax(id * ,l,r);
else
{
return max(querymax(id * ,l,mid),querymax(id * + ,mid + ,r));
}
} int querymin(int id,int l,int r)
{
if (tree[id].l >= l && tree[id].r <= r)
{
return tree[id].MIN;
}
int mid = (tree[id].l + tree[id].r) / ;
if (l > mid) return querymin(id * + ,l,r);
else if (r <= mid) return querymin(id * ,l,r);
else
{
return min(querymin(id * ,l,mid),querymin(id * + ,mid + ,r));
}
} int main()
{
int Q;
while (scanf("%d%d",&N,&Q) != EOF)
{
for (int i = ; i <= N ; i++) scanf("%d",&src[i]);
build(,,N);
while (Q--)
{
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",querymax(,l,r) - querymin(,l,r));
}
}
return ;
}

HDU 4027 Can you answer these queries?

每次操作把区间内所有值开跟好向下取整,最大的数最多开7次根到1,所以直接做区间长度等于区间和直接结束

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXN = ;
const int INF = 0x3f3f3f3f;
struct node
{
int l,r;
LL sum;
bool flag;
}tree[MAXN * ];
LL src[MAXN]; void build(int id,int l,int r)
{
tree[id].l = l;
tree[id].r = r;
if (l == r)
{
tree[id].sum = src[l];
return;
}
int mid = (l + r) / ;
build(id * ,l,mid);
build(id * + ,mid + ,r);
tree[id].sum = tree[id * ].sum + tree[id * + ].sum;
} void push_down(int id)
{
if (tree[id].l == tree[id].r)
{
tree[id].sum = (LL)sqrt(1.0 * tree[id].sum);
return;
}
push_down(id * );
push_down(id * + );
tree[id].sum = tree[id * + ].sum + tree[id * ].sum;
} void update(int id,int l,int r)
{
if (tree[id].l >= l && tree[id].r <= r)
{
if (tree[id].sum == (LL)(tree[id].r - tree[id].l + ))
return;
push_down(id);
return;
}
int mid = (tree[id].l + tree[id].r) / ;
if (l > mid) update(id * + ,l,r);
else if (r <= mid) update(id * ,l,r);
else
{
update(id * ,l,mid);
update(id * + ,mid + ,r);
}
tree[id].sum = tree[id * ].sum + tree[id * + ].sum;
} LL query(int id,int l,int r)
{
if (tree[id].l >= l && tree[id].r <= r)
{
return tree[id].sum;
}
int mid = (tree[id].l + tree[id].r) / ;
if (l > mid) return query(id * + ,l,r);
else if (r <= mid) return query(id * ,l,r);
else
{
return query(id * ,l,mid) + query(id * + ,mid + ,r);
}
} int main()
{
int N,M,kase = ;
while (scanf("%d",&N) != EOF)
{
for (int i = ; i <= N ; i++) scanf("%I64d",&src[i]);
scanf("%d",&M);
build(,,N);
printf("Case #%d:\n",kase++);
while (M--)
{
int op;
scanf("%d",&op);
if (op == )
{
int l,r;
scanf("%d%d",&l,&r);
if (l > r) swap(l,r);
update(,l,r);
}
else
{
int l,r;
scanf("%d%d",&l,&r);
if (l > r) swap(l,r);
printf("%I64d\n",query(,l,r));
}
}
putchar('\n');
}
return ;
}

HDU 1540 Tunnel Warfare

维护左连续长,右连续长,最大连续长度

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXN = ;
const int INF = 0x3f3f3f3f;
struct node
{
int l,r;
int leftlen,rightlen,maxlen;
}tree[MAXN * ];
stack<int>s; void build(int id,int l,int r)
{
tree[id].l = l;
tree[id].r = r;
tree[id].leftlen = tree[id].rightlen = tree[id].maxlen = r - l + ;
if (l == r) return;
int mid = (l + r) / ;
build(id * ,l,mid);
build(id * + ,mid + ,r);
} void push_up(int id)
{
//leftlen;
if (tree[id * ].leftlen == tree[id * ].r - tree[id * ].l + )
{
tree[id].leftlen = tree[id * ].r - tree[id * ].l + + tree[id * + ].leftlen;
}
else tree[id].leftlen = tree[id * ].leftlen;
//right len
if (tree[id * + ].rightlen == tree[id * + ].r - tree[id * + ].l + )
{
tree[id].rightlen = tree[id * + ].r - tree[id * + ].l + + tree[id * ].rightlen;
}
else tree[id].rightlen = tree[id * + ].rightlen;
tree[id].maxlen = max(tree[id * ].maxlen,tree[id * + ].maxlen);
tree[id].maxlen = max(tree[id].maxlen,tree[id * ].rightlen + tree[id * + ].leftlen);
} void update(int id,int pos,bool flag)
{
if (tree[id].l == tree[id].r)
{
if (flag)
tree[id].maxlen = tree[id].leftlen = tree[id].rightlen = ;
else
tree[id].maxlen = tree[id].leftlen = tree[id].rightlen = ;
return;
}
int mid = (tree[id].l + tree[id].r) / ;
if (pos > mid) update(id * + ,pos,flag);
if (pos <= mid) update(id * ,pos,flag);
push_up(id);
} int query(int id,int pos)
{
if (tree[id].l == tree[id].r ||
tree[id].maxlen == tree[id].r - tree[id].l + )
{
return tree[id].maxlen;
}
int mid = (tree[id].l + tree[id].r) / ;
if (pos <= mid)//左半段
{
int tmppos = tree[id * ].r - tree[id * ].rightlen + ;
if (pos >= tmppos) return tree[id * ].rightlen + tree[id * + ].leftlen;
else return query(id * ,pos);
}
else
{
int tmppos = tree[id * + ].l + tree[id * + ].leftlen - ;
if (pos <= tmppos) return tree[id * + ].leftlen + tree[id * ].rightlen;
else return query(id * + ,pos);
}
} int main()
{
//freopen("sample.txt","r",stdin);
int N,Q;
while (scanf("%d%d",&N,&Q) != EOF)
{
build(,,N);
while (!s.empty()) s.pop();
while (Q--)
{
char op[];
scanf("%s",op);
if (op[] == 'D')
{
int pos;
scanf("%d",&pos);
s.push(pos);
update(,pos,true);
}
if (op[] == 'Q')
{
int pos;
scanf("%d",&pos);
printf("%d\n",query(,pos));
}
if (op[] == 'R')
{
if (s.empty()) continue;
int x = s.top();
s.pop();
update(,x,false);
}
}
}
return ;
}

HDU 3794 Assign the task

其实就一个树形转线性

别的随便做,代码里有排除爆炸手写的树形转线性存一下模版

#pragma comment(linker, "/STACK:102400000,102400000")
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXN = ;
int L[MAXN],R[MAXN];
const int INF = 0x3f3f3f3f;
struct node
{
int l,r;
int val;
bool flag;
}tree[MAXN * ]; void build(int id,int l,int r)
{
tree[id].l = l;
tree[id].r = r;
tree[id].val = -;
tree[id].flag = false;
if (l == r) return;
int mid = (l + r) / ;
build(id * ,l,mid);
build(id * + ,mid + ,r);
} void push_down(int id)
{
if (tree[id].flag)
{
tree[id * ].flag = tree[id * + ].flag = true;
tree[id * ].val = tree[id * + ].val = tree[id].val;
tree[id].flag = false;
}
} void update(int id,int l,int r,int val)
{
if (tree[id].l >= l && tree[id].r <= r)
{
tree[id].flag = true;
tree[id].val = val;
return;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) / ;
if (l > mid) update(id * + ,l,r,val);
else if (r <= mid) update(id * ,l,r,val);
else
{
update(id * ,l,mid,val);
update(id * + ,mid + ,r,val);
}
} int query(int id,int pos)
{
if (tree[id].l == pos && tree[id].r == pos)
{
return tree[id].val;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) / ;
if (pos > mid) return query(id * + ,pos);
else return query(id * ,pos);
} /*
int Stack[MAXN * 2],top;
int deg[MAXN];
int Index,seq[MAXN];
bool vis[MAXN];
queue<int>q[MAXN]; void get_seq(int st)//这段先序遍历树形转线性我应该是不会的
{
int pos;
int idx = 0;
top = 1;
Stack[top] = st;
memset(vis,false,sizeof(vis));
while (top)
{
pos = Stack[top];
if (!vis[pos])
{
vis[pos] = true;
seq[++idx] = pos;
L[pos] = idx;
}
if (!q[pos].empty())
{
Stack[++top] = q[pos].front();
q[pos].pop();
}
else
{
R[pos] = idx;
top--;
}
}
}*/
vector<int>q[MAXN];
int Index;
int deg[MAXN];
bool vis[MAXN]; void get_seq(int u)
{
L[u] = ++Index;
vis[u] = true;
for (int i = ; i < (int)q[u].size() ; i++)
{
int v = q[u][i];
if (vis[v]) continue;
get_seq(v);
}
R[u] = Index;
} int main()
{
//freopen("sample.txt","r",stdin);
int T,kase = ;
scanf("%d",&T);
int N,Q;
while(T--)
{
memset(deg,,sizeof(deg));
scanf("%d",&N);
for (int i = ; i <= N ; i++) q[i].clear();
for (int i = ; i < N ; i++)
{
int u,v;
scanf("%d%d",&u,&v);
//q[v].push(u);
q[v].push_back(u);
deg[u]++;
}
build(,,N);
int root = ;
for (int i = ; i <= N ; i++)
{
if (deg[i] == )
{
root = i;
break;
}
}
Index = ;
memset(vis,false,sizeof(vis));
//printf("%d\n",root);
get_seq(root);
printf("Case #%d:\n",kase++);
//for (int i = 1 ; i <= N ; i++) printf("%d %d\n",L[i],R[i]);
scanf("%d",&Q);
while (Q--)
{
char op[];
scanf("%s",op);
if (op[] == 'C')
{
int x;
scanf("%d",&x);
printf("%d\n",query(,L[x]));
}
else
{
int x,val;
scanf("%d%d",&x,&val);
//printf("%d %d\n",L[x],R[x]);
update(,L[x],R[x],val);
}
}
}
return ;
}

HDU 4578 Transformation

这题很吊看这里 http://www.cnblogs.com/Commence/p/4871352.html

HDU 4614 Vases and Flowers

如果某个点可以插花,那么这个点值为1,由于他就是从左往右一直插花,实际上就是二分+区间和的问题。

然后查询一个区间最左边的1和最右边的1

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXN = ;
const int INF = 0x3f3f3f3f;
struct node
{
int l,r;
int sum,lazy,lft,rht;
}tree[MAXN * ];
int N,Q; void build(int id,int l,int r)
{
tree[id].l = l;
tree[id].r = r;
tree[id].sum = r - l + ;
tree[id].lft = l;
tree[id].rht = r;
tree[id].lazy = ;
if (l == r) return;
int mid = (l + r) / ;
build(id * ,l,mid);
build(id * + ,mid + ,r);
} void push_up(int id)
{
if (tree[id].l == tree[id].r) return;
tree[id].sum = tree[id * ].sum + tree[id * + ].sum;
if (tree[id * ].lft != -) tree[id].lft = tree[id * ].lft;
else tree[id].lft = tree[id * + ].lft;
if (tree[id * + ].rht != -) tree[id].rht = tree[id * + ].rht;
else tree[id].rht = tree[id * ].rht;
} void push_down(int id)
{
if (tree[id].l == tree[id].r) return;
if (tree[id].lazy == )
{
tree[id * ].lft = tree[id * ].l;
tree[id * ].rht = tree[id * ].r;
tree[id * ].sum = tree[id * ].r - tree[id * ].l + ;
tree[id * ].lazy = ;
tree[id * + ].lft = tree[id * + ].l;
tree[id * + ].rht = tree[id * + ].r;
tree[id * + ].sum = tree[id * + ].r - tree[id * + ].l + ;
tree[id * + ].lazy = ;
}
if (tree[id].lazy == -)
{
tree[id * ].lft = -;
tree[id * ].rht = -;
tree[id * ].sum = ;
tree[id * ].lazy = -;
tree[id * + ].lft = -;
tree[id * + ].rht = -;
tree[id * + ].sum = ;
tree[id * + ].lazy = -;
}
tree[id].lazy = ;
} void update(int id,int l,int r,int val)
{
if (tree[id].l >= l && tree[id].r <= r)
{
if (val == )
{
if (tree[id].sum == ) return;
tree[id].sum = ;
tree[id].lft = -;
tree[id].rht = -;
tree[id].lazy = -;
return;
}
else if (val == )
{
if (tree[id].r - tree[id].l + == tree[id].sum) return;
tree[id].sum = tree[id].r - tree[id].l + ;
tree[id].lazy = ;
tree[id].lft = tree[id].l;
tree[id].rht = tree[id].r;
return;
}
}
push_down(id);
int mid = (tree[id].l + tree[id].r) / ;
if (l > mid) update(id * + ,l,r,val);
else if (r <= mid) update(id * ,l,r,val);
else
{
update(id * ,l,mid,val);
update(id * + ,mid + ,r,val);
}
push_up(id);
} int getsum(int id,int l,int r)
{
if (tree[id].l >= l && tree[id].r <= r)
{
return tree[id].sum;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) / ;
if (l > mid) return getsum(id * + ,l,r);
else if (r <= mid) return getsum(id * ,l,r);
else
{
return getsum(id * ,l,mid) + getsum(id * + ,mid + ,r);
}
} int queryleft(int id,int l,int r)
{
if (tree[id].l >= l && tree[id].r <= r)
{
return tree[id].lft;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) / ;
if (l > mid) return queryleft(id * + ,l,r);
else if (r <= mid) return queryleft(id * ,l,r);
else
{
int ret;
ret = queryleft(id * ,l,mid);
if (ret != -) return ret;
ret = queryleft(id * + ,mid + ,r);
return ret;
}
} int queryright(int id,int l,int r)
{
if (tree[id].l >= l && tree[id].r <= r)
{
return tree[id].rht;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) / ;
if (l > mid) return queryright(id * + ,l,r);
else if (r <= mid) return queryright(id * ,l,r);
else
{
int ret = queryright(id * + ,mid + ,r);
if (ret != -) return ret;
return queryright(id * ,l,mid);
}
} int binseach(int A,int F)
{
int tmp = getsum(,A,N);
if (tmp == ) return - ;
if (tmp < F) return N;
int l = A,r = N;
while (l < r)
{
int mid = (l + r) / ;
int val = getsum(,A,mid);
if (val >= F)
{
r = mid;
}
else l = mid + ;
}
return l;
} int main()
{
int T;
scanf("%d",&T);
while (T--)
{
scanf("%d%d",&N,&Q);
build(,,N);
while (Q--)
{
int op;
scanf("%d",&op);
if (op == )
{
int A,F;
scanf("%d%d",&A,&F);
A++;
int tmp = binseach(A,F);
if (tmp == -)
{
puts("Can not put any one.");
continue;
}
printf("%d %d\n",queryleft(,A,tmp) - ,queryright(,A,tmp) - );
update(,A,tmp,);
}
else
{
int l,r;
scanf("%d%d",&l,&r);
l++;
r++;
printf("%d\n",r - l + - getsum(,l,r));
update(,l,r,);
}
}
putchar('\n');
}
return ;
}

HDU 4553 约会安排

一个优先级问题,优先女神,然后吊斯

女神的询问中先在吊死中找如果吊死中可以满足就同时更新吊死和女神的那个区间值详情看代码

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXN = ;
const int INF = 0x3f3f3f3f;
struct node
{
int l,r;
int lmax,rmax,mmax;
int lmax1,rmax1,mmax1;
}tree[MAXN * ]; void build(int id,int l,int r)
{
tree[id].l = l;
tree[id].r = r;
tree[id].lmax = tree[id].rmax = tree[id].mmax = r - l + ;
tree[id].lmax1 = tree[id].rmax1 = tree[id].mmax1 = r - l + ;
if (l == r) return;
int mid = (l + r) / ;
build(id * ,l,mid);
build(id * + ,mid + ,r);
} void push_up(int id)
{
if (tree[id].r == tree[id].l) return;
tree[id].lmax = tree[id * ].lmax;
if (tree[id * ].lmax == tree[id * ].r - tree[id * ].l + )
tree[id].lmax += tree[id * + ].lmax;
tree[id].rmax = tree[id * + ].rmax;
if (tree[id * + ].rmax == tree[id * + ].r - tree[id * + ].l + )
tree[id].rmax += tree[id * ].rmax;
tree[id].mmax = max(tree[id * ].mmax,tree[id * + ].mmax);
tree[id].mmax = max(tree[id].mmax,tree[id * ].rmax + tree[id * + ].lmax); tree[id].lmax1 = tree[id * ].lmax1;
if (tree[id * ].lmax1 == tree[id * ].r - tree[id * ].l + )
tree[id].lmax1 += tree[id * + ].lmax1;
tree[id].rmax1 = tree[id * + ].rmax1;
if (tree[id * + ].rmax1 == tree[id * + ].r - tree[id * + ].l + )
tree[id].rmax1 += tree[id * ].rmax1;
tree[id].mmax1 = max(tree[id * ].mmax1,tree[id * + ].mmax1);
tree[id].mmax1 = max(tree[id].mmax1,tree[id * ].rmax1 + tree[id * + ].lmax1);
} void push_down(int id)
{
if (tree[id].l == tree[id].r) return;
if (tree[id].mmax == )
{
tree[id * ].lmax = tree[id * ].rmax = tree[id * ].mmax = ;
tree[id * + ].lmax = tree[id * + ].rmax = tree[id * + ].mmax = ;
}
if (tree[id].mmax == tree[id].r - tree[id].l + )
{
tree[id * ].lmax = tree[id * ].rmax = tree[id * ].mmax = tree[id * ].r - tree[id * ].l + ;
tree[id * + ].lmax = tree[id * + ].rmax = tree[id * + ].mmax = tree[id * + ].r - tree[id * + ].l + ;
}
if (tree[id].mmax1 == )
{
tree[id * ].lmax1 = tree[id * ].rmax1 = tree[id * ].mmax1 = ;
tree[id * + ].lmax1 = tree[id * + ].rmax1 = tree[id * + ].mmax1 = ;
}
if (tree[id].mmax1 == tree[id].r - tree[id].l + )
{
tree[id * ].lmax1 = tree[id * ].rmax1 = tree[id * ].mmax1 = tree[id * ].r - tree[id * ].l + ;
tree[id * + ].lmax1 = tree[id * + ].rmax1 = tree[id * + ].mmax1 = tree[id * + ].r - tree[id * + ].l + ;
}
} int query(int id,int x)
{
if (tree[id].mmax < x) return ;
if (tree[id].lmax >= x) return tree[id].l;
if (tree[id * ].mmax >= x) return query(id * ,x);
if (tree[id * ].rmax + tree[id * + ].lmax >= x)
return tree[id * ].r- tree[id * ].rmax + ;
return query(id * + ,x);
} int query1(int id,int x)
{
if (tree[id].mmax1 < x) return ;
if (tree[id].lmax1 >= x) return tree[id].l;
if (tree[id * ].mmax1 >= x) return query1(id * ,x);
if (tree[id * ].rmax1 + tree[id * + ].lmax1 >= x)
return tree[id * ].r- tree[id * ].rmax1 + ;
return query1(id * + ,x);
} void update(int id,int l,int r)
{
if (tree[id].l == l && tree[id].r == r)
{
tree[id].mmax = tree[id].lmax = tree[id].rmax = tree[id].r - tree[id].l + ;
tree[id].mmax1 = tree[id].lmax1 = tree[id].rmax1 = tree[id].r - tree[id].l + ;
return;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) / ;
if (l > mid) update(id * + ,l,r);
else if (r <= mid) update(id * ,l,r);
else
{
update(id * ,l,mid);
update(id * + ,mid + ,r);
}
push_up(id);
} void diors(int id,int l,int r)
{
if (tree[id].l == l && tree[id].r == r)
{
tree[id].mmax = tree[id].lmax = tree[id].rmax = ;
return;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) / ;
if (l > mid) diors(id * + ,l,r);
else if (r <= mid) diors(id * ,l,r);
else
{
diors(id * ,l,mid);
diors(id * + ,mid + ,r);
}
push_up(id);
} void godness(int id,int l,int r)
{
if (tree[id].l == l && tree[id].r == r)
{
tree[id].mmax = tree[id].lmax = tree[id].rmax = ;
tree[id].mmax1 = tree[id].lmax1 = tree[id].rmax1 = ;
return;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) / ;
if (l > mid) godness(id * + ,l,r);
else if (r <= mid) godness(id * ,l,r);
else
{
godness(id * ,l,mid);
godness(id * + ,mid + ,r);
}
push_up(id);
} int main()
{
//freopen("sample.txt","r",stdin);
int T,kase = ;
scanf("%d",&T);
while (T--)
{
printf("Case %d:\n",kase++);
int N,M;
scanf("%d%d",&N,&M);
build(,,N);
while (M--)
{
char op[];
scanf("%s",op);
if (op[] == 'D')
{
int x;
scanf("%d",&x);
int tmp = query(,x);
if (tmp == ) puts("fly with yourself");
else
{
diors(,tmp,tmp + x - );
printf("%d,let's fly\n",tmp);
}
}
else if (op[] == 'N')
{
int x;
scanf("%d",&x);
int tmp = query(,x);
if (tmp != )
{
godness(,tmp,tmp + x - );
printf("%d,don't put my gezi\n",tmp);
continue;
}
tmp = query1(,x);
if (tmp != )
{
godness(,tmp,tmp + x - );
printf("%d,don't put my gezi\n",tmp);
continue;
}
printf("wait for me\n");
}
else
{
int l,r;
scanf("%d%d",&l,&r);
printf("I am the hope of chinese chengxuyuan!!\n");
update(,l,r);
}
}
}
return ;
}

POJ 1177 Picture

线段树扫描线矩形周长并

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXN = ;
struct node
{
int l,r;
int cnt;
int lf,rf;
int numseg;
int c;
bool lcover,rcover;
}tree[MAXN * ]; struct Line
{
int y;
int x1,x2;
int f;
friend bool operator < (const Line &a,const Line &b)
{
return a.y < b.y;
}
}line[MAXN];
int x[MAXN],debug; void build(int id,int l,int r)
{
tree[id].l = l;
tree[id].r = r;
tree[id].lf = x[l];
tree[id].rf = x[r];
tree[id].cnt = ;
tree[id].numseg = ;
tree[id].c = ;
tree[id].lcover = tree[id].rcover = false;
if (l + == r) return;
int mid = (l + r) / ;
build(id * ,l,mid);
build(id * + ,mid,r);
} void callen(int id)
{
if (tree[id].c > )
{
tree[id].cnt = tree[id].rf - tree[id].lf;
tree[id].numseg = ;
tree[id].lcover = tree[id].rcover = true;
return;
}
if (tree[id].l + == tree[id].r)
{
tree[id].cnt = ;
tree[id].numseg = ;
tree[id].lcover = tree[id].rcover = false;
}
else
{
// printf("%d %d %d\n",tree[id].cnt,tree[id * 2].cnt ,tree[id * 2 + 1].cnt);
// printf("%d %d %d %d\n",tree[id * 2].l,tree[id * 2].r,tree[id * 2 + 1].l,tree[id * 2 + 1].r);
tree[id].cnt = tree[id * ].cnt + tree[id * + ].cnt;
tree[id].lcover = tree[id * ].lcover;
tree[id].rcover = tree[id * + ].rcover;
tree[id].numseg = tree[id * ].numseg + tree[id * + ].numseg;
if (tree[id * ].rcover && tree[id * + ].lcover) tree[id].numseg--;
}
} void update(int id,Line e)
{
if (tree[id].lf == e.x1 && tree[id].rf == e.x2)
{
tree[id].c += e.f;
// printf("%d %d %d %d %d %d %d\n",debug,tree[id].lf,tree[id].rf,tree[id].cnt,tree[id].c,tree[id].l,tree[id].r);
callen(id);
return;
}
if (e.x2 <= tree[id * ].rf) update(id * ,e);
else if (e.x1 >= tree[id * + ].lf) update(id * + ,e);
else
{
Line tmp = e;
tmp.x2 = tree[id * ].rf;
update(id * ,tmp);
tmp = e;
tmp.x1 = tree[id * + ].lf;
update(id * + ,tmp);
}
callen(id);
} int main()
{
int n;
while (scanf("%d",&n) != EOF)
{
int cas = ;
int x1,x2,y1,y2;
debug = ;
for (int i = ; i < n ; i++)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
line[cas].x1 = x1;
line[cas].x2 = x2;
line[cas].y = y1;
line[cas].f = ;
x[cas] = x1;
cas++;
line[cas].x1 = x1;
line[cas].x2 = x2;
line[cas].y = y2;
line[cas].f = -;
x[cas] = x2;
cas++;
}
sort(line,line + cas);
sort(x,x + cas);
int num = unique(x,x + cas) - x;
build(,,num - );
int ret = ,last = ;
for (int i = ; i < cas - ; i++)
{
debug++;
update(,line[i]);
ret += tree[].numseg * * (line[i + ].y - line[i].y);
ret += abs(tree[].cnt - last);
// printf("%d %d %d %d\n",line[i].x1,line[i].x2,line[i].y,tree[1].cnt);
// printf("%d\n\n",ret);
last = tree[].cnt;
}
update(,line[cas - ]);
ret += abs(tree[].cnt - last);
printf("%d\n",ret);
}
return ;
}

HDU 1542 Atlantis

线段树扫描线举行面积并

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXN = ;
const int INF = 0x3f3f3f3f;
int N; struct node
{
int l,r;
double lf,rf;
int c;
double cnt;
}tree[MAXN * ]; struct Line
{
double x1,x2;
double y;
int f;
friend bool operator < (const Line &a,const Line &b)
{
return a.y < b.y;
}
}line[MAXN];
double x[MAXN]; void build(int id,int l,int r)
{
tree[id].l = l;
tree[id].r = r;
tree[id].lf = x[l];
tree[id].rf = x[r];
tree[id].c = ;
tree[id].cnt = ;
if (l + == r) return;
int mid = (l + r) / ;
build(id * ,l,mid);
build(id * + ,mid,r);
} void callen(int id)
{
if (tree[id].c > )
{
tree[id].cnt = tree[id].rf - tree[id].lf;
return;
}
if (tree[id].l + == tree[id].r)
{
tree[id].cnt = ;
}
else
tree[id].cnt = tree[id * ].cnt + tree[id * + ].cnt;
} void update(int id,Line e)
{
if (tree[id].lf == e.x1 && tree[id].rf == e.x2)
{
tree[id].c += e.f;
callen(id);
return;
}
if (tree[id * ].rf >= e.x2) update(id * ,e);
else if (e.x1 >= tree[id * + ].lf) update(id * + ,e);
else
{
Line tmp = e;
tmp.x2 = tree[id * ].rf;
update(id * ,tmp);
tmp = e;
tmp.x1 = tree[id * + ].lf;
update(id * + ,tmp);
}
callen(id);
} int main()
{
int kase = ;
while (scanf("%d",&N) != EOF)
{
if (N == ) break;
int cas = ;
for (int i = ; i < N ; i++)
{
double x1,x2,y1,y2;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
line[cas].x1 = x1;
line[cas].x2 = x2;
line[cas].y = y1;
line[cas].f = ;
x[cas++] = x1;
line[cas].x1 = x1;
line[cas].x2 = x2;
line[cas].y = y2;
line[cas].f = -;
x[cas++] = x2;
}
sort(x,x + cas);
sort(line,line + cas);
int num = unique(x ,x + cas) - x;
build(,,num - );
double ret = ;
update(,line[]);
for (int i = ; i < cas ; i++)
{
ret += (line[i].y - line[i - ].y) * tree[].cnt;
update(,line[i]);
}
printf("Test case #%d\n",kase++);
printf("Total explored area: %.2lf\n\n",ret);
}
return ;
}

HDU 1255 覆盖的面积

矩形被覆盖2次以上的面积并。这个你要理解下这类问题是怎么解决的

首先c只有的被完全区间的时候会更新,区间被覆盖一次的长度表示什么,并不是一定就只覆盖了一次,

详细的看看callen函数。

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXN = ;
struct node
{
int l,r;
int c;
double lf,rf;
double cnt,more;
}tree[MAXN * ]; struct Line
{
double x1,x2;
double y;
int f;
friend bool operator < (const Line &a,const Line &b)
{
return a.y < b.y;
}
}line[MAXN];
double x[MAXN]; void build(int id,int l,int r)
{
tree[id].l = l;
tree[id].r = r;
tree[id].lf = x[l];
tree[id].rf = x[r];
tree[id].cnt = tree[id].more = tree[id].c = ;
if (l + == r) return;
int mid = (l + r) / ;
build(id * ,l,mid);
build(id * + ,mid,r);
} void callen(int id)
{
if (tree[id].c >= )
{
tree[id].more = tree[id].rf - tree[id].lf;
return;
}
if (tree[id].c == )
{
tree[id].cnt = tree[id].rf - tree[id].lf;
if (tree[id].l + == tree[id].r) tree[id].more = ;
else tree[id].more = tree[id * ].cnt + tree[id * + ].cnt;
}
else
{
if (tree[id].l == tree[id].r - )
tree[id].cnt = tree[id].more = ;
else
{
tree[id].cnt = tree[id * ].cnt + tree[id * + ].cnt;
tree[id].more = tree[id * ].more + tree[id * + ].more;
}
}
} void update(int id,Line e)
{
if (tree[id].lf == e.x1 && tree[id].rf == e.x2)
{
tree[id].c += e.f;
// printf("%d %d %d %d %d %d %d\n",debug,tree[id].lf,tree[id].rf,tree[id].cnt,tree[id].c,tree[id].l,tree[id].r);
callen(id);
return;
}
if (e.x2 <= tree[id * ].rf) update(id * ,e);
else if (e.x1 >= tree[id * + ].lf) update(id * + ,e);
else
{
Line tmp = e;
tmp.x2 = tree[id * ].rf;
update(id * ,tmp);
tmp = e;
tmp.x1 = tree[id * + ].lf;
update(id * + ,tmp);
}
callen(id);
}
int main()
{
int T;
scanf("%d",&T);
while (T--)
{
int N;
scanf("%d",&N);
int cas = ;
for (int i = ; i < N ; i++)
{
double x1,x2,y1,y2;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
line[cas].x1 = x1;
line[cas].x2 = x2;
line[cas].y = y1;
line[cas].f = ;
x[cas++] = x1;
line[cas].x1 = x1;
line[cas].x2 = x2;
line[cas].y = y2;
line[cas].f = -;
x[cas++] = x2;
}
sort(line,line + cas);
sort(x,x + cas);
int num = unique(x,x + cas) - x;
build(,,num - );
update(,line[]);
double ret = ;
for (int i = ; i < cas ; i++)
{
ret += (line[i].y - line[i - ].y) * tree[].more;
update(,line[i]);
}
printf("%.2lf\n",ret);
}
return ;
}

HDU 3642 Get The Treasury

线段树扫面线三维体积并,要求三次的内容。由于Z的绝对值小于500,所以可以枚举z

然后化为2唯来做

如何计算callen 中的once,twice,more是关键,理解很关键

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == ? b : gcd(b, a % b);}
const int MAXN = ;
const int INF = 0x3f3f3f3f;
struct node
{
int l,r;
int lf,rf;
int once,twice,more;
int c;
}tree[MAXN * ];
int x[MAXN],z[MAXN]; struct Line
{
int y;
int x1,x2;
int z1,z2;
int f;
friend bool operator < (const Line &a,const Line &b)
{
return a.y < b.y;
}
}line[MAXN],res[MAXN]; void build(int id,int l,int r)
{
tree[id].l = l;
tree[id].r = r;
tree[id].lf = x[l];
tree[id].rf = x[r];
tree[id].c = ;
tree[id].once = tree[id].twice = tree[id].more = ;
if (l + == r) return;
int mid = (l + r) / ;
build(id * ,l,mid);
build(id * + ,mid,r);
} void callen(int id)
{
if (tree[id].c >= )
{
tree[id].more = tree[id].rf - tree[id].lf;
tree[id].once = tree[id].twice = ;
return;
}
else if (tree[id].c == )
{
if (tree[id].l + == tree[id].r)
{
tree[id].more = ;
tree[id].twice = tree[id].rf - tree[id].lf;
tree[id].once = ;
return;
}
else
{
tree[id].more = tree[id * ].once + tree[id * ].twice + tree[id * ].more
+ tree[id * + ].once + tree[id * + ].twice + tree[id * + ].more;
tree[id].twice = tree[id].rf - tree[id].lf - tree[id].more;
tree[id].once = ;
}
}
else if (tree[id].c == )
{
if (tree[id].l + == tree[id].r)
{
tree[id].more = tree[id].twice = ;
tree[id].once = tree[id].rf - tree[id].lf;
}
else
{
tree[id].more = tree[id * ].more + tree[id * ].twice
+ tree[id * + ].more + tree[id * + ].twice;
tree[id].twice = tree[id * ].once + tree[id * + ].once;
tree[id].once = tree[id].rf - tree[id].lf - tree[id].more - tree[id].twice;
}
}
else
{
if (tree[id].l == tree[id].r - )
{
tree[id].more = tree[id].twice = tree[id].once = ;
}
else
{
tree[id].more = tree[id * ].more + tree[id * + ].more;
tree[id].twice = tree[id * ].twice + tree[id * + ].twice;
tree[id].once = tree[id * ].once + tree[id * + ].once;
}
}
} void update(int id,Line e)
{
if (tree[id].lf == e.x1 && tree[id].rf == e.x2)
{
tree[id].c += e.f;
callen(id);
return;
}
if (tree[id * ].rf >= e.x2) update(id * ,e);
else if (e.x1 >= tree[id * + ].lf) update(id * + ,e);
else
{
Line tmp = e;
tmp.x2 = tree[id * ].rf;
update(id * ,tmp);
tmp = e;
tmp.x1 = tree[id * + ].lf;
update(id * + ,tmp);
}
callen(id);
}
int main()
{
int T,kase = ;
scanf("%d",&T);
while (T--)
{
int N;
scanf("%d",&N);
int cas = ;
for (int i = ; i < N ; i++)
{
int x1,x2,y1,y2,z1,z2;
scanf("%d%d%d%d%d%d",&x1,&y1,&z1,&x2,&y2,&z2);
line[cas].x1 = x1;
line[cas].x2 = x2;
line[cas].z1 = z1;
line[cas].z2 = z2;
line[cas].f = ;
line[cas].y = y1;
x[cas] = x1;
z[cas++] = z1; line[cas].x1 = x1;
line[cas].x2 = x2;
line[cas].z1 = z1;
line[cas].z2 = z2;
line[cas].f = -;
line[cas].y = y2;
x[cas] = x2;
z[cas++] = z2;
}
sort(line,line + cas);
sort(x,x + cas);
sort(z,z + cas);
int num = unique(x,x + cas) - x;
build(,,num - );
int step = unique(z,z + cas) - z;
LL ret = ,area = ;
for (int i = ; i < step - ; i++)
{
int tot = ;
for (int j = ; j < cas ; j++)
{
if (line[j].z1 <= z[i] && line[j].z2 > z[i])
res[tot++] = line[j];
}
area = ;
update(,res[]);
for (int j = ; j < tot ; j++)
{
area += (LL)(res[j].y - res[j - ].y) * tree[].more;
update(,res[j]);
}
ret += area * (LL)(z[i + ] - z[i]);
}
printf("Case %d: %I64d\n",kase++,ret);
}
return ;
}

离散处理题目。求区间内不同数字的和,和不同数字的个数

Uvalive 5970 An Average Game

离散右端点排序每次标记上一次出现的位置

#include<bits/stdc++.h>
using namespace std;
const int MAXN = ;
#define LL long long
struct node {
int l,r;
int idx;
friend bool operator < (const node &a,const node &b) {
if (a.r == b.r) return a.l < b.l;
return a.r < b.r;
}
}src[MAXN];
int N,Q;
LL A[MAXN];
pair<LL,LL>ans[MAXN ]; struct treenode {
int l,r;
int sum;
}tree[MAXN * ]; void build(int id,int l,int r) {
tree[id].l = l;
tree[id].r = r;
tree[id].sum = ;
if (l >= r) return;
int mid = (l + r) / ;
build(id * ,l,mid);
build(id * + ,mid + ,r);
} void update(int id,int pos,bool flag) {
if (tree[id].l == pos && tree[id].r == pos) {
if (flag) tree[id].sum = ;
else tree[id].sum = ;
return;
}
int mid = (tree[id].l + tree[id].r) / ;
if (pos <= mid) update(id * ,pos,flag);
else update(id * + ,pos,flag);
tree[id].sum = tree[id * ].sum + tree[id * + ].sum;
} int query(int id,int l,int r) {
if (tree[id].l >= l && tree[id].r <= r) {
return tree[id].sum;
}
int mid = (tree[id].l + tree[id].r) / ;
if (r <= mid) return query(id * ,l,r);
else if (l > mid) return query(id * + ,l,r);
else {
return query(id * ,l,mid) + query(id * + ,mid + ,r);
}
} struct IntervalTree
{
LL sum[MAXN * ];
void build(){memset(sum,,sizeof(sum));}
void update(int o,int l,int r,int pos,int val)
{
if(l == r)
{
sum[o] += val;
return;
}
int mid = (l + r) >> ;
if(pos <= mid)update(o << ,l,mid,pos,val);
else update(o<< | ,mid + ,r,pos,val);
sum[o]=sum[o << ]+sum[o << |];
}
LL query(int o,int l,int r,int q1,int q2)
{
if(q1 <= l && r <= q2)return sum[o];
int mid=(l + r)>>;
LL ans=;
if(q1 <= mid)ans += query(o << ,l,mid,q1,q2);
if(q2 > mid)ans += query(o << | ,mid + ,r,q1,q2);
return ans;
}
}Tree; map<int,int>vis;
int main() {
int T,kase = ;
cin >> T;
while (T--) {
cin >> N;
for (int i = ; i <= N ; i++) cin >> A[i];
cin >> Q;
for (int i = ; i <= Q ; i++) { cin >> src[i].l >> src[i].r; if (src[i].l > src[i].r) swap(src[i].l,src[i].r); }
for (int i = ; i <= Q ; i++) src[i].idx = i;
vis.clear();
sort(src + ,src + + Q);
build(,,N);
int curpos = ;
for (int i = ; i <= Q ; i++) {
while (curpos <= N && curpos <= src[i].r) {
if (vis[A[curpos]]) update(,vis[A[curpos]],true);
update(,curpos,false);
vis[A[curpos]] = curpos;
curpos++;
}
ans[src[i].idx].first = (LL)query(,src[i].l,src[i].r);
} Tree.build();
vis.clear();
int cur = ;
for(int i = ; i <= Q ; i++)
{
for(; cur <= N && cur <= src[i].r ; cur++)
{
if(vis[A[cur]])Tree.update(,,N,vis[A[cur]],-A[cur]);
Tree.update(,,N,cur,A[cur]);
vis[A[cur]] = cur;
}
ans[src[i].idx].second = Tree.query(,,N,src[i].l,src[i].r);
}
// for (int i = 1 ; i <= Q ; i++) cout << ans[i].first << " " << ans[i].second << endl;
printf("Case %d:\n",kase++);
for (int i = ; i <= Q ; i++) printf("%.6lf\n",(1.0 * ans[i].second) / (1.0 * ans[i].first));
}
return ;
}
 

Kuangbin 带你飞-线段树专题 题解的更多相关文章

  1. Kuangbin 带你飞-基础计算几何专题 题解

    专题基本全都是模版应用.贴一下模版 平面最近点对 const double INF = 1e16; ; struct Point { int x,y; int type; }; double dist ...

  2. kuangbin带你飞 并查集 题解

    做这套题之前一直以为并查集是很简单的数据结构. 做了才发现自己理解太不深刻.只看重片面的合并集合.. 重要的时发现每个集合的点与这个根的关系,这个关系可以做太多事情了. 题解: POJ 2236 Wi ...

  3. 【kuangbin带你飞】 MST专题

    唉,被班级合唱和复变考试搞得心力交瘁.新算法学不进去,更新下吧 A - Til the Cows Come Home The Head Elder of the tropical island of ...

  4. vj线段树专题

    vj线段树专题题解 单点更新模板 void build(int x,int l,int r){//sum[x]控制l-r区域 if(l==r){Sum[x]=num[l];return ;} int ...

  5. 「kuangbin带你飞」专题十七 AC自动机

    layout: post title: 「kuangbin带你飞」专题十七 AC自动机 author: "luowentaoaa" catalog: true tags: - ku ...

  6. [kuangbin带你飞]专题1-23题目清单总结

    [kuangbin带你飞]专题1-23 专题一 简单搜索 POJ 1321 棋盘问题POJ 2251 Dungeon MasterPOJ 3278 Catch That CowPOJ 3279 Fli ...

  7. 「kuangbin带你飞」专题二十 斜率DP

    layout: post title: 「kuangbin带你飞」专题二十 斜率DP author: "luowentaoaa" catalog: true tags: mathj ...

  8. 「kuangbin带你飞」专题二十二 区间DP

    layout: post title: 「kuangbin带你飞」专题二十二 区间DP author: "luowentaoaa" catalog: true tags: - ku ...

  9. 「kuangbin带你飞」专题十九 矩阵

    layout: post title: 「kuangbin带你飞」专题十九 矩阵 author: "luowentaoaa" catalog: true tags: mathjax ...

随机推荐

  1. 生产者与消费者-N:1-基于list

    多个生产者/一个消费者: /** * 生产者 */ public class P { private MyStack stack; public P(MyStack stack) { this.sta ...

  2. linux常用命令补充详细

    1.ls命令 就是list的缩写,通过ls 命令不仅可以查看linux文件夹包含的文件,而且可以查看文件权限(包括目录.文件夹.文件权限)查看目录信息等等 常用参数搭配: ls -a 列出目录所有文 ...

  3. 排查实时tail功能cpu占用过高问题

    “你的python应用cpu占用快90%了!!!”,良哥朝我眨了眨布满血丝的眼睛“不会吧”,我心想:我这是好的啊 没接触过kafka的同学可以先了解下:([http://www.jasongj.com ...

  4. HDFS伪分布式环境搭建

    (一).HDFS shell操作 以上已经介绍了如何搭建伪分布式的Hadoop,既然环境已经搭建起来了,那要怎么去操作呢?这就是本节将要介绍的内容: HDFS自带有一些shell命令,通过这些命令我们 ...

  5. PHP 用Symfony VarDumper Component 调试

    Symfony VarDumper 类似 php var_dump() 官方文档写的安装方法 : 按照步骤 就可以在 running any PHP code  时候使用了 In order to h ...

  6. 制作一个简易计算器——基于Android Studio实现

    一个计算器Android程序的源码部分分为主干和细节两部分. 一.主干 1. 主干的构成 计算器的布局 事件(即计算器上的按钮.文本框)监听 实现计算 2. 详细解释 假设我们的项目名为Calcula ...

  7. 《学习OpenCV》课后习题解答8

    题目:(P126) 本章完整讲述了基本的输入/输出编程以及OpenCV的数据结构.下面的练习是基于前面的知识做一些应用,为后面大程序的实现提供帮助. a.创建一个程序实现以下功能:(1)从视频文件中读 ...

  8. js定时器实现图片轮播

    效果展示如下: setInterval(moverleft,3000);定时器设置为3秒,而且实现图片下方的小圆点序号跟图片对应,点击小圆点也能切换图片. 代码如下: <!DOCTYPE htm ...

  9. StrutsResultSupport的使用

    在有特殊情况时:如果没有异常信息,但是有错误并且有错误信息等内容:此时也需要进行友好的错误处理的话,那么可以借助StrutsResultSupport 返回结果类型来实现特定处理.此种方式先需要继承S ...

  10. 【bzoj4998】星球联盟 LCT+并查集

    题目描述 在遥远的S星系中一共有N个星球,编号为1…N.其中的一些星球决定组成联盟,以方便相互间的交流.但是,组成联盟的首要条件就是交通条件.初始时,在这N个星球间有M条太空隧道.每条太空隧道连接两个 ...