1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
| #include <bits/stdc++.h> #define MAXN 1000005 using namespace std; inline int read(){ int x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9'){ if (ch=='-') f=-1; ch=getchar(); } while (ch>='0'&&ch<='9'){ x=(x<<3)+(x<<1)+(ch^'0'); ch=getchar(); } return x*f; } namespace SegmentTree{ struct node{ int l,r; int tag,val; inline int len(){ return r-l+1; } }tree[MAXN<<2]; #define lc i<<1 #define rc i<<1|1 inline void Cover(int i){ tree[i].tag=1,tree[i].val=tree[i].len(); } inline void pushup(int i){ tree[i].val=tree[lc].val+tree[rc].val; } inline void pushdown(int i){ if (tree[i].tag){ Cover(lc),Cover(rc); tree[i].tag=0; } } void Build(int i,int l,int r){ tree[i].l=l,tree[i].r=r; tree[i].val=tree[i].tag=0; if (l==r) return ; int mid=(l+r)>>1; Build(lc,l,mid); Build(rc,mid+1,r); } void Update(int i,int L,int R){ if (L<=tree[i].l&&tree[i].r<=R){ Cover(i); return ; } int mid=(tree[i].l+tree[i].r)>>1; pushdown(i); if (L<=mid) Update(lc,L,R); if (mid<R) Update(rc,L,R); pushup(i); } int Query(int i,int L,int R){ if (L<=tree[i].l&&tree[i].r<=R){ return tree[i].val; } int mid=(tree[i].l+tree[i].r)>>1,ans=0; pushdown(i); if (L<=mid) ans+=Query(lc,L,R); if (mid<R) ans+=Query(rc,L,R); return ans; } } using namespace SegmentTree; struct query{ int l,r; int val; }Q[MAXN],A[MAXN]; inline bool operator < (const query &A,const query &B){ return A.val>B.val; } inline bool Covered(int l,int r){ return (r-l+1)==Query(1,l,r); } int n,q; inline bool Check(int pos){ Build(1,1,n); for (register int i=1;i<=pos;++i){ A[i]=Q[i]; } sort(A+1,A+1+pos); int lmin,lmax,rmin,rmax; lmin=lmax=A[1].l; rmin=rmax=A[1].r; for (register int i=2;i<=pos;++i){ if (A[i].val==A[i-1].val){ lmin=min(lmin,A[i].l); lmax=max(lmax,A[i].l); rmin=min(rmin,A[i].r); rmax=max(rmax,A[i].r); if (lmax>rmin) return 1; } else { if (Covered(lmax,rmin)) return 1; Update(1,lmin,rmax); lmin=lmax=A[i].l; rmin=rmax=A[i].r; } } if (Covered(lmax,rmin)) return 1; return 0; } int main(){ n=read(),q=read(); for (register int i=1;i<=q;++i){ Q[i]=query{read(),read(),read()}; } int l=1,r=q; int ans=0; while (l<=r){ int mid=(l+r)>>1; if (Check(mid)) ans=mid,r=mid-1; else l=mid+1; } printf("%d\n",ans); }
|