Click to open link
A (Hdu 1166 enemy soldiers) Chinese decent, line tree single point update, to find a period of interval and
#include <stdio.h> #include <string.h> #include <stack> #include <string> #include <math.h > #include <queue> #include <set> #include <algorithm> #include <iostream> #include <
Vector> #include <map> using namespace std; #define LL Long long #define INF 1<<31 #define N 50010 #define MOD 1000000007 struct node {int l,r,sum;}
tree[n<<2];
void pushup (int rt) {tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;} void build (int l,int R,int RT) {
Tree[rt].l=l;
Tree[rt].r=r;
tree[rt].sum=0;
if (l==r) {scanf ("%d", &tree[rt].sum);
return;
} int mid= (TREE[RT].L+TREE[RT].R) >>1;
Build (l,mid,rt<<1);
Build (mid+1,r,rt<<1|1);
Pushup (RT);
} void Updata (int x,int y,int RT) {if (TREE[RT].L==TREE[RT].R) {tree[rt].sum+=y;
return;
} int mid= (TREE[RT].L+TREE[RT].R) >>1; if (x<=mid) Updata (x,y,rt<<1);
else Updata (x,y,rt<<1|1);
Pushup (RT);
} int query (int x,int y,int RT) {if (tree[rt].l==x&&tree[rt].r==y) {return tree[rt].sum;
} int mid= (TREE[RT].L+TREE[RT].R) >>1;
if (y<=mid) return query (x,y,rt<<1);
else if (x>mid) return query (X,Y,RT<<1|1);
else return query (x,mid,rt<<1) +query (mid+1,y,rt<<1|1);
} int main () {int i,j,n,m,t,x,y,ca=0;
scanf ("%d", &t);
while (t--) {scanf ("%d", &n);
Build (1,n,1);
Char s[10];
printf ("Case%d:\n", ++CA);
while (scanf ("%s", s), s[0]!= ' E ') {scanf ("%d%d", &x,&y);
if (s[0]== ' Q ') printf ("%d\n", Query (x,y,1));
else if (s[0]== ' A ') updata (x,y,1);
else if (s[0]== ' s ') Updata (x,-y,1);;
}} return 0; }
B (Hdu 1754 I Hate It) Chinese decent, Segment tree single point update, find interval maximum value
#include <stdio.h> #include <string.h> #include <stack> #include <string> #include <math.h > #include <queue> #include <set> #include <algorithm> #include <iostream> #include <
Vector> #include <map> using namespace std; #define LL Long long #define INF 1<<31 #define N 200010 struct Node {int l,r,max;}
tree[n<<2];
void build (int l,int R,int RT) {tree[rt].l=l;
Tree[rt].r=r; if (l==r) {scanf ("%d", &tree[rt].
MAX);
return;
} int mid= (R+L) >>1;
Build (l,mid,rt<<1);
Build (mid+1,r,rt<<1|1); TREE[RT]. Max=max (Tree[rt<<1]. MAX,TREE[RT<<1|1].
MAX);
} int ans; void query (int l,int r,int RT) {if (tree[rt].l==l&&tree[rt].r==r) {Ans=max (Ans,tree[rt].
MAX);
return;
} int mid= (TREE[RT].L+TREE[RT].R) >>1;
if (l>mid) query (l,r,rt<<1|1);
else if (r<=mid) query (l,r,rt<<1);
else {query (l,mid,rt<<1);
Query (mid+1,r,rt<<1|1); }} void Updata (int X,int Y,int RT) {if (TREE[RT].L==TREE[RT].R) {Tree[rt].
Max=y;
return;
} int mid= (TREE[RT].L+TREE[RT].R) >>1;
if (x>mid) Updata (x,y,rt<<1|1);
else Updata (x,y,rt<<1); TREE[RT]. Max=max (Tree[rt<<1]. MAX,TREE[RT<<1|1].
MAX);
} int main () {int i,j,n,m,x,y;
Char s[3];
while (scanf ("%d%d", &n,&m)!=-1) {build (1,n,1);
for (i=1;i<=m;i++) {scanf ("%s%d%d", s,&x,&y);
if (s[0]== ' Q ') {ans=-1;
Query (x,y,1);
printf ("%d\n", ans);
} else Updata (x,y,1);
}} return 0; }
The interval update interval summation of C (POJ 3468 A simple problem with integers) segment tree
#include <stdio.h> #include <string.h> #include <stack> #include <string> #include <math.h > #include <queue> #include <set> #include <algorithm> #include <iostream> #include <
Vector> #include <map> using namespace std;
#define LL Long long #define INF 1<<31 #define N 100010 struct Node {int l,r;
LL sum,add;//Add the number not directly to the leaf node, but first into the add}tree[n<<2];
void pushup (int rt) {tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;} void build (int l,int R,int RT) {
Tree[rt].l=l;tree[rt].r=r;
Tree[rt].sum=tree[rt].add=0;
if (l==r) {scanf ("%lld", &tree[rt].sum);
return;
} int mid= (TREE[RT].L+TREE[RT].R) >>1;
Build (l,mid,rt<<1);
Build (mid+1,r,rt<<1|1);
Pushup (RT);
} void Pushdown (int rt) {int len=tree[rt].r-tree[rt].l+1;
tree[rt<<1].add+=tree[rt].add;
tree[rt<<1|1].add+=tree[rt].add; TREE[RT<<1].SUM+=TREE[RT]. add* (LEN-LEN/2);
tree[rt<<1|1].sum+=tree[rt].add* (LEN/2);
Tree[rt].add=0;
} LL query (int x,int y,int RT) {if (tree[rt].l==x&&tree[rt].r==y) return tree[rt].sum;
int mid= (TREE[RT].L+TREE[RT].R) >>1;
Pushdown (RT);
if (y<=mid) return query (x,y,rt<<1);
else if (x>mid) return query (X,Y,RT<<1|1);
else return query (x,mid,rt<<1) +query (mid+1,y,rt<<1|1);
} void Updata (int x,int y,ll Z,int rt) {if (tree[rt].l==x&&tree[rt].r==y) {tree[rt].add+=z;
tree[rt].sum+= (y-x+1) *z;
return;
} int mid= (TREE[RT].L+TREE[RT].R) >>1;
Pushdown (RT);
if (y<=mid) Updata (x,y,z,rt<<1);
else if (x>mid) Updata (x,y,z,rt<<1|1);
else {updata (x,mid,z,rt<<1);
Updata (mid+1,y,z,rt<<1|1);
} pushup (RT);
} int main () {int i,j,n,m;
Char s[3];
int x, y;
LL Z;
while (scanf ("%d%d", &n,&m)!=-1) { Build (1,n,1);
while (m--) {scanf ("%s", s);
if (s[0]== ' Q ') {scanf ("%d%d", &x,&y);
printf ("%lld\n", Query (x,y,1));
} else {scanf ("%d%d%lld", &x,&y,&z);
Updata (x,y,z,1);
}}} return 0; }
D (POJ 2528 Mayor ' s posters) segment Tree + discretization, is to put posters on the wall, the current poster can cover the previous poster, ask how many posters can be seen at the end
#include <stdio.h> #include <string.h> #include <stack> #include <string> #include <math.h > #include <queue> #include <set> #include <algorithm> #include <iostream> #include <
Vector> #include <map> using namespace std; #define LL Long long #define INF 1<<31 #define N 20010 struct Node {int l,r,c;}
tree[n<<2]; struct line {int l,r;}
A[n];
int Key[n],tot,ans;
BOOL Mark[n];
void build (int l,int R,int RT) {tree[rt].l=l;tree[rt].r=r;
tree[rt].c=0;
if (l==r) return;
int mid= (TREE[RT].L+TREE[RT].R) >>1;
Build (l,mid,rt<<1);
Build (mid+1,r,rt<<1|1);
} int find_p (int x) {int low=1,high=tot;
while (low<=high) {int mid= (Low+high) >>1;
if (key[mid]==x) return mid;
else if (X<key[mid]) high=mid-1;
else low=mid+1;
}} void Updata (int l,int r,int C,int rt) {if (tree[rt].l==l&&tree[rt].r==r) {Tree[rt].c=c;
return;
} if (tree[rt].c) {tree[rt<<1].c=tree[rt<<1|1].c=tree[rt].c;
tree[rt].c=0;
} int mid= (TREE[RT].L+TREE[RT].R) >>1;
if (r<=mid) Updata (l,r,c,rt<<1);
else if (l>mid) Updata (l,r,c,rt<<1|1);
else {updata (l,mid,c,rt<<1);
Updata (mid+1,r,c,rt<<1|1); }} void query (int rt) {if (TREE[RT].C) {if (mark[tree[rt].c]==0) {mark[tree[rt].c]=1
;
ans++;
} return;
} query (rt<<1);
Query (rt<<1|1);
} int main () {int i,j,n,m,t;
scanf ("%d", &t);
while (t--) {memset (mark,0,sizeof (Mark));
scanf ("%d", &n);
tot=0;
for (i=1;i<=n;i++) {scanf ("%d%d", &A[I].L,&A[I].R);
KEY[++TOT]=A[I].L;KEY[++TOT]=A[I].R;
} sort (Key+1,key+1+tot); Tot=unique (Key+1,key+1+tot)-(key+1);Array de-weight//printf ("%d\n", tot);
Build (1,tot,1);
for (i=1;i<=n;i++)//discretization {int l=find_p (A[I].L);
int r=find_p (A[I].R);
Updata (l,r,i,1);
} ans=0;
Query (1);
printf ("%d\n", ans);
} return 0; }
E (Hdu 1698 just a hook) or interval operation, code click to open the link
F (Zoj 1610 Count the Colors)
#include <stdio.h> #include <string.h> #include <stack> #include <string> #include <math.h > #include <queue> #include <set> #include <algorithm> #include <iostream> #include <
Vector> #include <map> using namespace std; #define LL Long long #define INF 1<<31 #define N 8010 struct Node {int l,r,c;}
tree[n<<2];
int Col[n],ans[n];//col[i] is the kind of the I position color, ans[i] is the number of segments of the color I void build (int l,int R,int RT) {tree[rt].l=l;
Tree[rt].r=r;
Tree[rt].c=-1;
if (r-l==1) return;//coloring is a small interval int mid= (l+r) >>1;
Build (l,mid,rt<<1);
Build (mid,r,rt<<1|1);
} void Updata (int l,int r,int C,int rt) {if (tree[rt].l==l&&tree[rt].r==r) {tree[rt].c=c;
return;
} if (tree[rt].r-tree[rt].l==1) return;
int mid= (TREE[RT].L+TREE[RT].R) >>1;
if (tree[rt].c!=-1) {tree[rt<<1].c=tree[rt<<1|1].c=tree[rt].c;
Tree[rt].c=-1; } IF (r<=mid) Updata (l,r,c,rt<<1);
else if (l>=mid) Updata (l,r,c,rt<<1|1);
else {updata (l,mid,c,rt<<1);
Updata (mid,r,c,rt<<1|1); }} void query (int rt) {if (tree[rt].c!=-1) {for (int i=tree[rt].l;i<tree[rt].r;i++) Col[i]
=TREE[RT].C;
return;
} if (tree[rt].r-tree[rt].l==1) return;
Query (rt<<1);
Query (rt<<1|1);
} int main () {int i,j,n,m;
while (scanf ("%d", &n)!=eof) {int x, y, Z;
Build (0,8000,1);
for (i=0;i<n;i++) {scanf ("%d%d%d", &x,&y,&z);
Updata (x,y,z,1);
} memset (ans,0,sizeof (ans));
memset (col,-1,sizeof (col));
Query (1);
for (i=0;i<=8000;i++) {if (col[i]==-1) continue;
if (col[i]!=col[i+1]) ans[col[i]]++; } for (i=0;i<=8000;i++) {if (ans[i]==0) contInue;
printf ("%d%d\n", i,ans[i]);
} puts ("");
} return 0; }
G Simple single-point update
#include <stdio.h> #include <string.h> #include <stack> #include <string> #include <math.h > #include <queue> #include <set> #include <algorithm> #include <iostream> #include <
Vector> #include <map> using namespace std; #define LL Long long #define INF 1<<30 #define N 50010 struct Node {int l,r,min,max;}
tree[n<<2];
int Resmin,resmax;
void build (int l,int R,int RT) {tree[rt].l=l;
Tree[rt].r=r; if (l==r) {scanf ("%d", &tree[rt].
Min); TREE[RT]. MAX=TREE[RT].
Min;
return;
} int mid= (R+L) >>1;
Build (l,mid,rt<<1);
Build (mid+1,r,rt<<1|1); TREE[RT]. Min=min (Tree[rt<<1]. MIN,TREE[RT<<1|1].
Min); TREE[RT]. Max=max (Tree[rt<<1]. MAX,TREE[RT<<1|1].
MAX); } void query (int l,int r,int RT) {if (tree[rt].l==l&&tree[rt].r==r) {resmin=min (Resmin,tree[rt].
Min); Resmax=max (Resmax,tree[rt].
MAX);
return;
} int mid= (TREE[RT].L+TREE[RT].R) >>1; if (l>mid) query (l, r,rt<<1|1);
else if (r<=mid) query (l,r,rt<<1);
else {query (l,mid,rt<<1);
Query (mid+1,r,rt<<1|1);
}} int main () {int m,n,j,i,a,b;
while (scanf ("%d%d", &n,&m)!=-1) {build (1,n,1);
for (i=0;i<m;i++) {resmin=inf;resmax=-inf;
scanf ("%d%d", &a,&b);
Query (a,b,1);
printf ("%d\n", resmax-resmin);
}} return 0; }
I (HDU 1540 tunnel Warfare) Single point update, interval merge, query
#include <stdio.h> #include <string.h> #include <stack> #include <string> #include <math.h > #include <queue> #include <set> #include <algorithm> #include <iostream> #include <
Vector> #include <map> using namespace std; #define LL Long long #define INF 1<<30 #define N 50010 struct Node {int l,r,lans,rans,ans;}
tree[n<<2]; void pushup (int rt) {if (tree[rt<<1].ans==tree[rt<<1].r-tree[rt<<1].l+1) tree[rt].lans=tree[
rt<<1].ans+tree[rt<<1|1].lans;
else tree[rt].lans=tree[rt<<1].lans; if (tree[rt<<1|1].ans==tree[rt<<1|1].r-tree[rt<<1|1].l+1) tree[rt].rans=tree[rt<<1|1].
ans+tree[rt<<1].rans;
else tree[rt].rans=tree[rt<<1|1].rans; tree[rt].ans= Max (Max (Tree[rt<<1].ans,tree[rt<<1|1].ans), tree[rt<<1].rans+tree[rt<<1|1]
. LANs);
} void Build (int l,int R,int RT) {tree[rt].l=l;tree[rt].r=r;tree[rt].lans=tree[rt].rans=tree[rt].ans=r-l+1;
if (l==r) return;
int mid= (L+R) >>1;
Build (l,mid,rt<<1);
Build (mid+1,r,rt<<1|1); } void Updata (int x,int rt,int c) {if (TREE[RT].L==TREE[RT].R) {tree[rt].ans=tree[rt].lans=tree[rt].rans=
C
return;
} int mid= (TREE[RT].L+TREE[RT].R) >>1;
if (x<=mid) Updata (X,RT<<1,C);
else Updata (X,RT<<1|1,C);
Pushup (RT); } int query (int x,int RT) {if (tree[rt].ans==0| |
tree[rt].ans==tree[rt].r-tree[rt].l+1) return Tree[rt].ans;
int mid= (TREE[RT].L+TREE[RT].R) >>1; if (X<=mid) {if (x>=tree[rt<<1].r-tree[rt<<1].rans+1) return Tree[rt<<1].ra
ns+tree[rt<<1|1].lans;
else return query (x,rt<<1); } else {if (x<=tree[rt<<1|1].l+tree[rt<<1|1].lans-1) return TREE[RT<<1].R
ans+tree[rt<<1|1].lans; else return QuEry (x,rt<<1|1);
}} int main () {int i,j,n,m,x;
Char str[3];
while (scanf ("%d%d", &n,&m)!=-1) {stack<int>s;
while (!s.empty ()) S.pop ();
Build (1,n,1);
while (m--) {scanf ("%s", str);
if (str[0]== ' D ') {scanf ("%d", &x);
Updata (x,1,0);
S.push (x);
} else if (str[0]== ' Q ') {scanf ("%d", &x);
printf ("%d\n", Query (x,1));
} else {x=s.top ();
S.pop ();
Updata (x,1,1);
}}} return 0; }
P (HDU 1542 Atlantis) scan line for rectangular area
#include <stdio.h> #include <string.h> #include <stack> #include <string> #include <math.h > #include <queue> #include <set> #include <algorithm> #include <iostream> #include <
Vector> #include <map> using namespace std;
#define LL Long long #define INF 1<<30 #define N l,r struct Node {int.
int c;//c is used to record overlapping cases double CNT,LF,RF;
CNT is used to calculate the length of Y, RF,LF is the corresponding real floating-point endpoint}tree[n<<2];
struct line {double x,y1,y2;
int F;
}line[n]; A segment parallel to the y-axis segment represents an array,//x is the x-coordinate of the segment, the coordinates of the lower and upper points of the Y1,Y2 segment//a rectangle, the left side of the edge F is 1, the right is-1,//used to record the overlap, can be calculated according to this, Nod node C double y[n];//record y-coordinate array bool CMP (line A,line b) {return a.x<b.x;} void build (int l,int R,int RT) {tree[rt].l=l;tree[
Rt].r=r;
tree[rt].cnt=tree[rt].c=0;
TREE[RT].LF=Y[L];TREE[RT].RF=Y[R];
if (l+1==r) return;
int mid= (L+R) >>1;
Build (l,mid,rt<<1);
Build (mid,r,rt<<1|1);
} void Calen (int rt) {if (tree[rt].c>0) {TREE[RT].CNT=TREE[RT].RF-TREE[RT].LF;
return;
} if (TREE[RT].L+1==TREE[RT].R) tree[rt].cnt=0;
else tree[rt].cnt=tree[rt<<1].cnt+tree[rt<<1|1].cnt;
} void Updata (int rt,line e) {if (e.y1==tree[rt].lf&&tree[rt].rf==e.y2) {tree[rt].c+=e.f;
Calen (RT);
return;
} if (E.Y2<=TREE[RT<<1].RF) Updata (rt<<1,e);
else if (E.Y1>=TREE[RT<<1|1].LF) Updata (rt<<1|1,e);
else {line tmp=e;
tmp.y2=tree[rt<<1].rf;
Updata (RT<<1,TMP);
Tmp=e;
tmp.y1=tree[rt<<1|1].lf;
Updata (RT<<1|1,TMP);
} calen (RT);
} int main () {int i,n,j,t,ca=1;
Double x1,x2,y1,y2;
while (scanf ("%d", &n), n) {t=1;
for (i=1;i<=n;i++) {scanf ("%lf%lf%lf%lf", &x1,&y1,&x2,&y2);
line[t].x=x1;line[t].y1=y1;line[t].y2=y2;line[t].f=1; Y[t]=y1; t++;
Line[t].x=x2;line[t].y1=y1;line[t].y2=y2;line[t].f=-1; Y[t]=y2;
t++;
} sort (line+1,line+t,cmp);
Sort (y+1,y+t);
Build (1,t-1,1);
Updata (1,line[1]);
Double ans=0;
for (i=2;i<t;i++) {ans+=tree[1].cnt* (line[i].x-line[i-1].x);
Updata (1,line[i]);
} printf ("Test case #%d\ntotal explored area:%.2f\n\n", Ca++,ans);
} return 0; }