zoukankan      html  css  js  c++  java
  • [codeforces]Round #537 (Div. 2)E. Tree

    题解:  q次查询每次查询k个点  k的总和不超过1e5  那就->虚树  这个题分为两部分  前面先对每次查询的点建虚树 其次计数  对于新树上的每个关键点(查询点)  他能影响的m的范围 必然大于以r为根的祖先节点的个数 然后我们单独考虑每个节点的贡献为 当前集合个数减去其祖先节点的个数  然后我们考虑把每个点按照dfs序的下标考虑贡献  转移分为两部分

          1.当前元素加入直接构成一个新集合

          2,当前元素加入可以加入到  m(当前集合个数)-祖先节点个数

    #include <bits/stdc++.h>
    #define ll long long
    #define inc(i,l,r) for(int i=l;i<=r;i++)
    const int MAXN=3e5+10;
    using namespace std;
    const ll inf=1e18;
    const ll MOD=1e9+7;
    vector<int>vec[MAXN];
    int f[MAXN][21];int dep[MAXN];
    int st[MAXN],tot;
    int p[MAXN],cnt1;
    vector<int>V;
    bool vis[MAXN];
    ll read(){
        ll x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return f*x;
    }
    ll Add(ll a, ll b){a+=b;if(a>=MOD)a-=MOD; return a;}
    ll Mult(ll a, ll b){return (a*b)%MOD;}
    void dfs(int v,int pre,int deep){
        dep[v]=deep;f[v][0]=pre;p[v]=++cnt1;
        for(int i=0;i<vec[v].size();i++){
        int u=vec[v][i];
        if(u!=pre){
            dfs(u,v,deep+1);
        }
        }
    }
    void dfs1(int v){
        inc(i,1,20)f[v][i]=f[f[v][i-1]][i-1];
        for(int i=0;i<vec[v].size();i++){
        int u=vec[v][i];
        if(u!=f[v][0])dfs1(u);
        }
    }
    int Lca(int u,int v){
        if(dep[u]<dep[v])swap(u,v);
        int tmp=dep[u]-dep[v];
        for(int i=0;i<=20;i++)if(tmp&(1<<i))u=f[u][i];
        if(u==v)return u;
        for(int i=20;i>=0;i--){
        if(f[u][i]!=f[v][i]){
            u=f[u][i];
            v=f[v][i];
        }
        }
        return f[u][0];
    }
    ll dp[2][305];
    void built(int x){
        V.push_back(x);
        if(!tot){st[++tot]=x;return ;}
        int lca=Lca(x,st[tot]);
        while(tot>1&&dep[lca]<dep[st[tot-1]]){
        vec[st[tot]].push_back(st[tot-1]);
        vec[st[tot-1]].push_back(st[tot]);
        tot--;
        }
        if(dep[st[tot]]>dep[lca]){
        vec[st[tot]].push_back(lca);
        vec[lca].push_back(st[tot]);
        tot--;
        V.push_back(lca);
        }
        if(!tot||dep[lca]>dep[st[tot]])st[++tot]=lca;
        st[++tot]=x;
    }
    int M[MAXN],St[MAXN],cnt;
    void dfs2(int x,int pre,int deep){
        if(vis[x])M[x]=deep+1,St[++cnt]=x;
        for(int i=0;i<vec[x].size();i++){
    	if(vec[x][i]!=pre){
    	    if(vis[x])dfs2(vec[x][i],x,deep+1);
    	    else dfs2(vec[x][i],x,deep);
    	}
        }
    }
    int n,m;
    bool cmp(int aa,int bb){return p[aa]<p[bb];}
    int main(){
        n=read();m=read();
        int u,v;
        for(int i=1;i<n;i++)u=read(),v=read(),vec[u].push_back(v),vec[v].push_back(u);
        dfs(1,0,0);dfs1(1);int k,q,r;
        for(int i=1;i<=n;i++)vec[i].clear();
        while(m--){
        k=read();q=read();r=read();
        tot=0;
        V.push_back(r);
        for(int i=1;i<=k;i++)v=read(),V.push_back(v),vis[v]=1;
        sort(V.begin(),V.end(),cmp);
        int sz=unique(V.begin(),V.end())-V.begin();
        for(int i=1;i<=sz;i++)built(V[i-1]);
        while(tot>1){vec[st[tot]].push_back(st[tot-1]),vec[st[tot-1]].push_back(st[tot]);tot--;}
        cnt=0;dfs2(r,0,0);
        int K=0;
        inc(i,1,q)dp[K][i]=0;
        dp[K][0]=1;
        for(int i=1;i<=cnt;i++){
    	K=1-K;
    	inc(j,0,q)dp[K][j]=0;
    	for(int j=0;j<=q;j++){
    	    if(j<q)dp[K][j+1]=Add(dp[K][j+1],dp[!K][j]);
    	    if(M[St[i]]<=j)dp[K][j]=Add(dp[K][j],Mult(dp[!K][j],j-M[St[i]]+1));
    	}
        }
        ll ans=0;
        inc(i,1,q)ans=Add(ans,dp[K][i]);
        printf("%lld
    ",ans);
        for(int i=0;i<V.size();i++)vec[V[i]].clear(),vis[V[i]]=0;
        V.clear();
        }
        return 0;
    }
  • 相关阅读:
    HDU 1025 Constructing Roads In JGShining's Kingdom (DP+二分)
    HDU 1158 Employment Planning
    HDU 2059 龟兔赛跑
    Csharp 简单操作Word模板文件
    Csharp windowform datagridview Clipboard TO EXCEL OR FROM EXCEL DATA 保存datagridview所有數據
    Csharp 讀寫文件內容搜索自動彈出 AutoCompleteMode
    Csharp windowform controls clear
    CSS DIV大图片右上角叠加小图片
    Csharp DataGridView自定义添加DateTimePicker控件日期列
    Csharp 打印Word文件默認打印機或選擇打印機設置代碼
  • 原文地址:https://www.cnblogs.com/wang9897/p/10352125.html
Copyright © 2011-2022 走看看