codeforces 960 F. Pathwalks(主席树)

题目链接:http://codeforces.com/contest/960/problem/F

思路:这题除了主席树,应该还有其他做法,不过刚好拿来学一学主席树。。。,可以给每一个节点建一颗线段树,而每颗线段树的节点对应的是到这个节点边的权值,线段树节点存的就是对应“权值区间“的边的最大值了。。。讲的不好,自己理解一下吧

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll inff = 0x3f3f3f3f3f3f3f3f;
#define FOR(i,a,b) for(int i(a);i<=(b);++i)
#define FOL(i,a,b) for(int i(a);i>=(b);--i)
#define REW(a,b) memset(a,b,sizeof(a))
#define inf int(0x3f3f3f3f)
#define si(a) scanf("%d",&a)
#define sl(a) scanf("%I64d",&a)
#define sd(a) scanf("%lf",&a)
#define ss(a) scanf("%s",a)
#define mod int(1e9+7)
#define lc (d<<1)
#define rc (d<<1|1)
#define P pair
#define pi acos(-1)
struct as{
int l,r,mx;}tr[100008*20];
int qw,rt[100008],dp[100008],n,m;
void add(int l,int r,int &x,int y,int z)
{
    if(!x) x=++qw; tr[x].mx=max(tr[x].mx,z);
    if(l==r)  return;
    int mid=(l+r)>>1;
    if(mid>=y)  add(l,mid,tr[x].l,y,z);
    else   add(mid+1,r,tr[x].r,y,z);
}
int query(int l,int r,int x,int k)
{
    if(l==r)  return tr[x].mx;
    int mid=(l+r)>>1;
    if(k<=mid)  return query(l,mid,tr[x].l,k);
    else    return max(tr[tr[x].l].mx,query(mid+1,r,tr[x].r,k));
}
int main()
{
    cin.tie(0);
    si(n),si(m);
    int x,y,z,s=0;
    FOR(i,1,m)
    {
        si(x),si(y),si(z);
        dp[i]=query(1,100000,rt[x],z-1)+1;
        add(1,100000,rt[y],z,dp[i]);
        s=max(s,dp[i]);
    }
    cout<

你可能感兴趣的:(主席树)