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; }
浙公网安备 33010602011771号