Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define endl '\n'
- using namespace std;
- const int N = 100007;
- const int NEUTRAL_VALUE = 0;
- template < class T, class UT, class MERGE_VALUE_VALUE, class MERGE_VALUE_UPDATE >
- struct binary_indexed_tree {
- vector < T > tree;
- int n;
- MERGE_VALUE_VALUE merge_values;
- MERGE_VALUE_UPDATE update_value;
- void build_tree(T *arr, int a, int b, int node) {
- if(a>b) return;
- if(a==b) {
- tree[node]=arr[a];
- return;
- }
- build_tree(arr,a,(a+b)>>1,node<<1);
- build_tree(arr,((a+b)>>1)+1,b,(node<<1)|1);
- tree[node]=merge_values(tree[node<<1],tree[(node<<1)|1]);
- }
- void update_tree(int a, int b, int pos, UT value, int node) {
- if(a>b || a>pos || b<pos) return;
- if(a==b) {
- tree[node]=update_value(tree[node],value);
- return;
- }
- update_tree(a,(a+b)>>1,pos,value,node<<1);
- update_tree(((a+b)>>1)+1,b,pos,value,(node<<1)|1);
- tree[node]=merge_values(tree[node<<1],tree[(node<<1)|1]);
- }
- T query_tree(int a, int b, int i, int j, int node) {
- if(a>b || a>j || b<i) return NEUTRAL_VALUE;
- if(a>=i && b<=j) return tree[node];
- return merge_values(query_tree(a,(a+b)>>1,i,j,node<<1),query_tree(((a+b)>>1)+1,b,i,j,(node<<1)|1));
- }
- void initialize(int k) {
- n=k;
- tree.assign(4*n+5,NEUTRAL_VALUE);
- }
- void initialize(T *arr, int k) {
- n=k;
- tree.assign(4*n+5,NEUTRAL_VALUE);
- build_tree(arr,1,n,1);
- }
- void update(int pos, UT value) {
- update_tree(1,n,pos,value,1);
- }
- T query(int l, int r) {
- return query_tree(1,n,l,r,1);
- }
- };
- struct merge_them {
- int operator () (const int &a, const int &b) const {
- return max(a,b);
- }
- };
- int n,m,from[N],to[N],w[N],arr[N];
- vector < int > v[N];
- binary_indexed_tree < int, int, merge_them, merge_them > it[N];
- int ans;
- int get(int which, int val) {
- vector < int >::iterator itr=upper_bound(v[which].begin(),v[which].end(),val);
- if(itr==v[which].end()) return 0;
- return it[which].query((int)(itr-v[which].begin())+1,(int)(v[which].size()));
- }
- void update(int which, int w, int val) {
- vector < int >::iterator itr=lower_bound(v[which].begin(),v[which].end(),w);
- int idx=(int)(itr-v[which].begin())+1;
- it[which].update(idx,val);
- }
- int main() {
- ios_base::sync_with_stdio(false);
- cin.tie(NULL);
- int i;
- scanf("%d %d", &n, &m);
- for(i=1;i<=m;i++) {
- scanf("%d %d %d", &from[i], &to[i], &w[i]);
- v[from[i]].push_back(w[i]);
- }
- for(i=1;i<=n;i++) {
- sort(v[i].begin(),v[i].end());
- if(v[i].size()>0) {
- it[i].initialize((int)(v[i].size()));
- }
- }
- for(i=m;i>=1;i--) {
- int curr=1+get(to[i],w[i]);
- update(from[i],w[i],curr);
- ans=max(ans,curr);
- }
- printf("%d\n", ans);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement