zoukankan      html  css  js  c++  java
  • 正睿 11.1 模拟赛题解

    T1

    毒瘤计数题,至少想假了 (5) 次。

    不难发现,(d) 不管是奇数还是偶数,都有一个中心点,我们考虑如果 (d) 为偶数,那么中心就是一个点,否则及时一条边,不难发现中间为一条边是好做的,我们直接预处理回答询问即可。至于偶数,我们可以遍历其邻点,然后对于哪些点我们枚举所有组合方式,减去不合法的即可。

    代码:

    #include<bits/stdc++.h>
    #define dd double
    #define ld long double
    #define ll long long
    #define uint unsigned int
    #define ull unsigned long long
    #define N 4010
    #define M number
    using namespace std;
    
    const int INF=0x3f3f3f3f;
    const int mod=1e9+7;
    
    template<typename T> inline void read(T &x) {
        x=0; int f=1;
        char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c == '-') f=-f;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        x*=f;
    }
    
    struct edge{
        int from,to,next;
        inline void Init(int fr_,int to_,int ne_){
            from=fr_;to=to_;next=ne_;
        }
    }li[N<<1];
    int head[N],tail=1;
    
    inline void Add(int from,int to){
        li[++tail].Init(from,to,head[from]);
        head[from]=tail;
    }
    
    int d[N][N][2],Dep[N],sum[N][N][2],Root,n,m,Tag,TwoPow[N];
    
    inline int ksm(int a,int b,int mod){
        int res=1;while(b){if(b&1) res=1ll*res*a%mod;a=1ll*a*a%mod;b>>=1;}return res;
    }
    
    inline void dfs(int k,int fa,int op){
        Dep[k]=Dep[fa]+1;d[Root][Dep[k]][op]++;
        for(int x=head[k];x;x=li[x].next){
            int to=li[x].to;
            if(Tag==x||(Tag^1)==x) continue;
            if(to==fa) continue;
            dfs(to,k,op);
        }
    }
    
    inline void Init(){
        read(n);
        for(int i=1;i<=n-1;i++){
            int from,to;read(from);read(to);
            Add(from,to);Add(to,from);
        }
        Dep[0]=-1;
        for(int i=2;i<=tail;i++){
            Tag=i;Root=i;dfs(li[i].from,0,0);dfs(li[i].to,0,1);
            sum[i][0][0]=d[i][0][0];sum[i][0][1]=d[i][0][1];
            for(int j=1;j<=n;j++){
                sum[i][j][0]=sum[i][j-1][0]+d[i][j][0];
                sum[i][j][1]=sum[i][j-1][1]+d[i][j][1];
            }
            // printf("li[%d].from=%d li[%d].to=%d
    ",i,li[i].from,i,li[i].to);
            // for(int j=1;j<=n;j++){
            //     printf("d[%d][%d][0]=%d d[%d][%d][1]=%d
    ",i,j,d[i][j][0],i,j,d[i][j][1]);
            // }
        }
        TwoPow[0]=1;
        for(int i=1;i<=n;i++) TwoPow[i]=1ll*TwoPow[i-1]*2%mod;
    }
    
    inline void Solve(){
        read(m);
        for(int i=1;i<=m;i++){
            int di;read(di);
            int Ans=0;
            if(di&1){
                int len=di/2;
                for(int j=2;j<=tail;j+=2){
                    int n1=d[j][len][0];
                    int n2=d[j][len][1];
                    int m=0;
                    if(len>=1) (m+=sum[j][len-1][0]+sum[j][len-1][1])%=mod;
                    Ans=(Ans+1ll*(TwoPow[n1]-1)*(TwoPow[n2]-1)%mod*TwoPow[m])%mod;
                }
            }
            else{
                for(int i=1;i<=n;i++){
                    int sum1=0,sum2=1;
                    for(int x=head[i];x;x=li[x].next){
                        // sum1=(sum1+d[x][di/2-1][1]);
                        if(di/2>=2) sum2=(sum2+sum[x][di/2-2][1])%mod;
                    }
                    int now=1;
                    for(int x=head[i];x;x=li[x].next){
                        // now=(now+1ll*(sum1-d[x][di/2-1][1])*d[x][di/2-1][1]%mod)%mod;
                        // now=1ll*now*(d[x][di/2-1][1]+1);
                        now=1ll*now*((TwoPow[d[x][di/2-1][1]]-1)+1)%mod;
                        (sum1+=(TwoPow[d[x][di/2-1][1]]-1))%=mod;
                    }
                    now--;now-=sum1;
                    Ans=(Ans+1ll*now*TwoPow[sum2]%mod)%mod;
                }
            }
            printf("%d
    ",(Ans%mod+mod)%mod);
        }
    }
    
    signed main(){
        freopen("my.in","r",stdin);
        freopen("my.out","w",stdout);
        Init();Solve();
        return 0;
    }
    

    T2

    二分图博弈学习笔记例题 3。

    链接

    T3

    这个题正解是用树上被增法,然而因为数据过水,所以暴力可做。据说出题人是随机建树。

    代码:

    #include<bits/stdc++.h>
    #define dd double
    #define ld long double
    #define ll long long
    #define uint unsigned int
    #define ull unsigned long long
    #define N 500010
    #define M number
    using namespace std;
    
    const int INF=0x3f3f3f3f;
    
    template<typename T> inline void read(T &x) {
    	x=0; int f=1;
    	char c=getchar();
    	for(;!isdigit(c);c=getchar()) if(c == '-') f=-f;
    	for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    	x*=f;
    }
    
    template<typename T> inline T Max(T a,T b){return a<b?b:a;}
    
    int n,m,tot;
    map<int,int> Map[N];
    vector<int> v[N],col[N];
    int From[N],To[N],Fa[N][32],Dep[N];
    
    inline void Dfs(int k,int f){
    	Dep[k]=Dep[f]+1;Fa[k][0]=f;
    	for(int i=1;i<=30;i++) Fa[k][i]=Fa[Fa[k][i-1]][i-1];
    	for(int to:v[k]){if(to==f) continue;Dfs(to,k);}
    }
    
    inline int GetLca(int a,int b){
    	if(Dep[a]<Dep[b]) swap(a,b);
    	for(int i=30;i>=0;i--) if(Dep[Fa[a][i]]>=Dep[b]) a=Fa[a][i];
    	if(a==b) return a;
    	for(int i=30;i>=0;i--) if(Fa[a][i]!=Fa[b][i]){a=Fa[a][i];b=Fa[b][i];}return Fa[a][0];
    }
    
    inline void Init(){
    	read(n);read(m);
    	for(int i=1;i<=m;i++){
    		int from,to,w;read(from);read(to);read(w);
    		if(!Map[from][to]){
    			Map[from][to]=++tot;Map[to][from]=tot;
    			v[from].push_back(to);v[to].push_back(from);
    			From[tot]=from;To[tot]=to;
    			col[tot].push_back(w);
    		}
    		else col[Map[from][to]].push_back(w);
    	}
    	Dfs(1,0);
    }
    
    inline void Solve(int a,int b){
    	int Lca=GetLca(a,b);
    	// printf("Lca=%d
    ",Lca);
    	vector<int> Road,c;Road.clear();
    	int k=a;while(k!=Lca){Road.push_back(k);k=Fa[k][0];}
    	Road.push_back(Lca);c.clear();
    	k=b;while(k!=Lca){c.push_back(k);k=Fa[k][0];}
    	for(int i=c.size()-1;i>=0;i--) Road.push_back(c[i]);
    	priority_queue<pair<int,int> > q[2];
    	q[0].push(make_pair(0,0));int o=0;
    	// for(int i=0;i<Road.size();i++) printf("%d ",Road[i]);
    	// puts("");
    	for(int i=0;i<Road.size()-1;i++){
    		// printf("i=%d
    ",i);
    		o^=1;int now=Map[Road[i]][Road[i+1]];
    		while(q[o].size()) q[o].pop();
    		for(int co:col[now]){
    			pair<int,int> Top=q[o^1].top();
    			if(co!=Top.second){q[o].push(make_pair(Top.first+1,co));}
    			else{
    				q[o^1].pop();
    				if(q[o^1].size()){
    					q[o].push(make_pair(Max(Top.first,q[o^1].top().first+1),co));
    				}
    				else q[o].push(make_pair(Top.first,co));
    				q[o^1].push(Top);
    			}
    		}
    	}
    	printf("%d
    ",Max(0,q[o].top().first-1));
    }
    
    int q;
    
    int main(){
    	// freopen("my.in","r",stdin);
    	// freopen("my.out","w",stdout);
    	Init();
    	read(q);
    	while(q--){
    		int a,b;read(a);read(b);
    		Solve(a,b);
    	}
    	return 0;
    }
    
  • 相关阅读:
    C# 从服务器下载文件
    不能使用联机NuGet 程序包
    NPOI之Excel——合并单元格、设置样式、输入公式
    jquery hover事件中 fadeIn和fadeOut 效果不能及时停止
    UVA 10519 !! Really Strange !!
    UVA 10359 Tiling
    UVA 10940 Throwing cards away II
    UVA 10079 Pizze Cutting
    UVA 763 Fibinary Numbers
    UVA 10229 Modular Fibonacci
  • 原文地址:https://www.cnblogs.com/TianMeng-hyl/p/15505553.html
Copyright © 2011-2022 走看看