hdoj5893

这题只需在sdoi2011染色的基础上,将边权转到点权。然后询问的时候在一条链上的情况,深度小的dfn+1查询。如果在一条链上还是同一个点,判断上次的两个是否相同,相同-1,然后直接返回。

 

数据里没有cost=0,的情况,没有询问a=b的情况,甚至lazy都不用清空,甚至update里x一直都不等于y,以至于不可能ql>qr。不过开始arr错了。

典型数据:


7 5
1 2 2
1 3 1
2 4 2
2 5 1
2 6 1

1 7 1

Q 3 5

Q 3 7

Q 3 7最后跳到同一个点,判断2边上次查询值一样,减1返回。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <cassert>
#include <stack>
#include <bitset>
#define mkp make_pair
#define err cout<<"err"<<endl
using namespace std;
const double EPS=1e-8;
typedef long long lon;
typedef unsigned long long ull;
typedef pair<short,short> pii;
const lon SZ=100010,SSZ=2*SZ,APB=4,one=1;
const lon INF=0x3f3f3f3f,mod=2147493647;
lon n,m,arr[SZ];
struct nd{
    int to,wt;
    nd(int a=0,int b=0):to(a),wt(b){}
};
vector<nd> mp[SZ];
int top[SZ],dfn[SZ],cnt;
int siz[SZ],hy[SZ],pre[SZ],dep[SZ];
int num[5*SZ],lc[5*SZ],rc[5*SZ];
int lazy[5*SZ];

void dfs1(int x,int p,int d)
{
    siz[x]=1,pre[x]=p,dep[x]=d;
    for(int i=0;i<mp[x].size();++i)
    {
        int to=mp[x][i].to;
        int wt=mp[x][i].wt;
        if(to!=p)
        {
            dfs1(to,x,d+1);
            arr[to]=wt;
            siz[x]+=siz[to];
            if(!hy[x]||siz[to]>siz[hy[x]])
            {
                hy[x]=to;
            }
        }
    }
}

void dfs2(int x,int p,int t)
{
    dfn[x]=++cnt;
    top[x]=t;
    if(hy[x])dfs2(hy[x],x,t);
    for(int i=0;i<mp[x].size();++i)
    {
        int to=mp[x][i].to;
        if(to!=p&&to!=hy[x])
        {
            dfs2(to,x,to);
        }
    }
}

void pushdown(int rt)
{
    if(lazy[rt]!=INF)
    {
        num[rt*2]=1;
        lc[rt*2]=rc[rt*2]=lazy[rt];
        num[rt*2+1]=1;
        lc[rt*2+1]=rc[rt*2+1]=lazy[rt];
        lazy[rt*2]=lazy[rt];
        lazy[rt*2+1]=lazy[rt];
        lazy[rt]=INF;
    }
}

void pushup(int rt)
{
    num[rt]=num[rt*2]+num[rt*2+1];
    if(rc[rt*2]==lc[rt*2+1])--num[rt];
    lc[rt]=lc[rt*2];
    rc[rt]=rc[rt*2+1];
}

void update(int ll,int rr,int rt,int ql,int qr,int delta)
{
    if(ll>rr||ql>qr)return;
    int mid=(ll+rr)/2;
    if(ll!=rr)pushdown(rt);
    if(ql<=ll&&rr<=qr)
    {
        num[rt]=1;
        lc[rt]=rc[rt]=delta;
        lazy[rt]=delta;
        return;
    }
    
    if(ql<=mid)update(ll,mid,rt*2,ql,qr,delta);
    if(qr>mid)update(mid+1,rr,rt*2+1,ql,qr,delta);
    pushup(rt);
}

int qry(int ll,int rr,int rt,int ql,int qr,int &cl,int &cr)
{
    if(ll>rr||ql>qr)return 0;
    int mid=(ll+rr)/2;
    if(ll!=rr)pushdown(rt);
    if(ql<=ll&&rr<=qr)
    {
        cl=lc[rt],cr=rc[rt];
        //cout<<"num: "<<num[rt]<<endl;
        return num[rt];
    }
    
    int res1=0,res2=0;
    int c1,c2,c3,c4;
    if(ql<=mid)res1=qry(ll,mid,rt*2,ql,qr,c1,c2);
    if(qr>mid)res2=qry(mid+1,rr,rt*2+1,ql,qr,c3,c4);
    //cout<<"ll: "<<ll<<" "<<rr<<endl;
    if(res2==0)cl=c1,cr=c2;
    else if(res1==0)cl=c3,cr=c4;
    else
    {
        if(c2==c3)--res1;
        cl=c1,cr=c4;
    }
    return res1+res2;
}

void update(int x,int y,int z)
{
    for(;top[x]!=top[y];)
    {
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        update(1,n,1,dfn[top[x]],dfn[x],z);
        x=pre[top[x]];
    }
    if(x==y)return;
    if(dep[x]>dep[y])swap(x,y);
    update(1,n,1,dfn[x]+1,dfn[y],z);
}

int qry(int x,int y)
{
    int res=0;
    lon last1=INF,last2=INF;
    for(;top[x]!=top[y];)
    {
        if(dep[top[x]]<dep[top[y]])swap(x,y),swap(last1,last2);
        int c1,c2;
        res+=qry(1,n,1,dfn[top[x]],dfn[x],c1,c2);
        if(c2==last1)--res;
        last1=c1;
        //cout<<"res: "<<res<<" "<<x<<" "<<top[x]<<endl;
        x=pre[top[x]];
    }
    if(x==y)return res-(last1==last2);
    if(dep[x]>dep[y])swap(x,y),swap(last1,last2);
    int c1,c2;
    res+=qry(1,n,1,dfn[x]+1,dfn[y],c1,c2);
    //cout<<"res: "<<res<<" "<<c1<<" "<<c2<<endl;
    if(c1==last1)--res;
    if(c2==last2)--res;
    return res;
}

void init()
{
    for(int i=1;i<=n-1;++i)
    {
        int a,b,c;
        cin>>a>>b>>c;
        mp[a].push_back(nd(b,c));
        mp[b].push_back(nd(a,c));
    }
    dfs1(1,-1,1);
    dfs2(1,-1,1);
    for(int i=1;i<=n;++i)
    {
        update(1,n,1,dfn[i],dfn[i],arr[i]);
    }
    //int c1,c2;
    //for(int i=1;i<=30;++i)cout<<num[i]<<endl;
    //cout<<"qry: "<<qry(1,n,1,2,2,c1,c2)<<endl;
    for(int i=1;i<=m;++i)
    {
        string ch;
        cin>>ch;
        int a,b,c;
        if(ch[0]=='C')
        {
            cin>>a>>b>>c;
            update(a,b,c);
            //int c1,c2;
            //cout<<"qry: "<<qry(1,n,1,1,2,c1,c2)<<endl;
        }
        else
        {
            cin>>a>>b;
            int res=qry(a,b);
            if(a==b)res=0;
            cout<<res<<endl;
        }
    }
}

void work()
{
    
}

void release()
{
    for(int i=1;i<=n;++i)
    {
        mp[i].clear();
        hy[i]=dep[i]=pre[i]=siz[i]=0;
        dfn[i]=top[i]=arr[i]=0;
    }
    cnt=0;
    
    memset(num,0,sizeof(num));
    memset(lc,0,sizeof(lc));
    memset(rc,0,sizeof(rc));
}

int main()
{
    std::ios::sync_with_stdio(0);
    //freopen("d:\\1.txt","r",stdin);
    int casenum;
    //cin>>casenum;
    //cout<<casenum<<endl;
    //for(int tim=1;tim<=casenum;++tim)
    for(int tim=1;cin>>n>>m;++tim)
    {
        memset(lazy,0x3f,sizeof(lazy));
        //cout<<"Case #"<<tim<<": ";
        init();
        work();
        release();
    }
    return 0;
}

 

 

posted @ 2019-06-06 10:52  degvx  阅读(138)  评论(0)    收藏  举报