As usual, Alice finishes her delicious cake at noon. Unfortunately, the smell of cake beckoned hungry Bob, and he decided to rob one piece of cake.
The cake is a convex polygon with N edges. At the beginning, Bob cut it along the diagonals. After M cuts, Bob decided to rob the 'largest' piece of cake. Strangely, in Bob's opinion, the piece has the most number of edge is the biggest one.
Please help Bob to find the 'largest' piece.
Input
There are multiple test cases (about 20).
The first line of each test case contains two integer number N, M (5 <= N <= 10000), indicating the number of point of the cake and the cut, respectively.
The following M lines contain two integer x, y (1 <= x, y <= N), denoting the index of the starting and ending cut point. (the index of points mark from 1 to N clockwise.)
The input will guarantee that all of the cuts will not intersect inside the cake, but they may cross each other at the edge of cake, and Bob won't cut along the initial edge of the cake.
Output
Output the maximal size (most number of edges) of the piece which Bob will get.
Sample Input
7 2 3 6 7 2
Sample Output
4 思路:线段树成段更新,首先把操作排序,保证切割的正确行(如样例中先(3,6)再(2,7)),然后每切一次,就把这一段的值赋成零,然后拿上一次剩下的减去跟新之后剩下的就是 这次的。刚开始没想到用减的方法维护,想直接用求和的方法求更新的这一段的边数,但想想这样是不太可行的,更新后相当于吧整段赋成1,但这样不行,所以就用线段树维护现在剩下的边数<strong><span style="font-size:18px;">#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #include<algorithm> using namespace std; const int maxn=100010; int n,m; struct CUT { int x,y; bool operator < (const CUT & a)const { return y-x<a.y-a.x; } }cut[maxn]; struct IntervalTree { int sum[maxn<<3]; int setv[maxn<<3]; void build(int o,int l,int r) { sum[o]=r-l+1; setv[o]=0; if(l==r)return ; int mid=(l+r)>>1; build(o<<1,l,mid); build(o<<1|1,mid+1,r); } void pushup(int o) { sum[o]=sum[o<<1]+sum[o<<1|1]; } void pushdown(int o) { if(setv[o]) { setv[o<<1]=setv[o<<1|1]=1; sum[o<<1]=sum[o<<1|1]=0; setv[o]=0; } } void update(int o,int l,int r,int q1,int q2) { if(q1<=l&&r<=q2) { sum[o]=0; setv[o]=1; return ; } pushdown(o); int mid=(l+r)>>1; if(q1<=mid)update(o<<1,l,mid,q1,q2); if(q2>mid)update(o<<1|1,mid+1,r,q1,q2); pushup(o); } }tree; int main() { while(scanf("%d%d",&n,&m)!=EOF) { for(int i=1;i<=m;i++) { scanf("%d%d",&cut[i].x,&cut[i].y); if(cut[i].x>cut[i].y) swap(cut[i].x,cut[i].y); } sort(cut+1,cut+1+m); tree.build(1,1,n); int ans=0,cnt=tree.sum[1]; for(int i=1;i<=m;i++) { tree.update(1,1,n,cut[i].x,cut[i].y-2); ans=max(ans,cnt-tree.sum[1]+2); cnt=tree.sum[1]; } printf("%d\n",max(ans,tree.sum[1])); } return 0; } </span></strong>