zoukankan      html  css  js  c++  java
  • 洛谷P4337 [ZJOI2018]线图(状压+搜索+乱搞)

    题面

    传送门

    题解

    妈呀调了我整整一天……

    题解太长了不写了可以去看(shadowice)巨巨的

    //minamoto
    #include<bits/stdc++.h>
    #define R register
    #define ull unsigned int
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=T->head[u],v=T->e[i].v;i;i=T->e[i].nx,v=T->e[i].v)
    #define gg(u) for(int i=u,v=lg[i&-i];i;i-=i&-i,v=lg[i&-i])
    using namespace std;
    char buf[1<<21],*p1=buf,*p2=buf;
    inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    int read(){
        R int res,f=1;R char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    const int N=5005,M=1e7+5,P=998244353,inv2=499122177;
    inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
    inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
    inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
    int ksm(R int x,R int y){
    	R int res=1;
    	for(;y;y>>=1,x=mul(x,x))if(y&1)res=mul(res,x);
    	return res;
    }
    const ull base1=998,base2=244;
    int n,k,ans;
    int deg[M],s[M],C[N][15],fac[15];
    struct Gr{
    	struct eg{int v,nx;}e[M];int head[M],tot,n;
    	inline void Add(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
    	inline void Pre(R int x){n=x,tot=1;fp(i,1,n)head[i]=0;}
    	int calc(){
    		int res=0;fp(i,1,n)deg[i]=s[i]=0;
    		fp(i,2,tot)++deg[e[i].v];
    		fp(u,1,n)for(int i=head[u];i;i=e[i].nx)s[u]+=deg[u]+deg[e[i].v]-3;
    		fp(i,1,n)res=add(res,mul(s[i],s[i]));
    		res=mul(res,inv2);
    		for(int i=2;i<=tot;i+=2){
    			int d=deg[e[i].v]+deg[e[i^1].v]-2;
    			res=(res+P-(d-1)*(d-1))%P;
    			res=(res+1ll*d*(d-1)*(d-2)/2)%P;
    		}
    		return res;
    	}
    }pool[3],*T,*E[2];
    int lg[N],pc[N];
    struct Tr{
    	ull f[15],q[15],mdzz;int siz[15],jc[15],to[15],n;
    	inline void Add(R int u,R int v){to[u]|=(1<<v);}
    	inline void clr(){fp(i,0,n-1)to[i]=0;n=0;}
    	void dfs(int u){
    		siz[u]=1;
    		gg(to[u])dfs(v),siz[u]+=siz[v];
    		int t=0;gg(to[u])q[++t]=f[v];
    		sort(q+1,q+1+t),q[t+1]=q[t]+1,q[0]=q[1]+1,f[u]=siz[u],jc[u]=1;
    		fp(i,1,t)f[u]=f[u]*base1+q[i];
    		for(int i=1,s=1,cnt=1;i<=t+1;++i)
    			q[i]==q[i-1]?(++cnt,s=mul(s,cnt)):(jc[u]=mul(jc[u],s),s=cnt=1);
    		jc[u]=ksm(jc[u],P-2),f[u]*=base2*siz[u];
    	}
    	inline void Pre(){dfs(0),mdzz=f[0];}
    	int sz[15],vis;
    	void calc(int u,int S){
    		sz[u]=1,vis|=(1<<u);
    		gg(to[u]&S)calc(v,S),sz[u]+=sz[v];
    		int t=0;gg(to[u]&S)q[++t]=f[v];
    		sort(q+1,q+1+t),f[u]=sz[u];
    		fp(i,1,t)f[u]=f[u]*base1+q[i];
    		f[u]*=base2*sz[u];
    	}
    	int ck(int S){
    		int mx=lg[S&-S];
    		fp(i,0,n-1)((S>>i&1)&&siz[i]>siz[mx])?mx=i:0;
    		vis=0,calc(mx,S);return vis==S?mx:-1;
    	}
    }qwq,*ntr;
    void Line(Gr *a,Gr *b){
    	b->Pre((a->tot-1)>>1);
    	fp(u,1,a->n)for(int i=a->head[u];i;i=a->e[i].nx)for(int j=a->e[i].nx;j;j=a->e[j].nx)
    		b->Add(i>>1,j>>1),b->Add(j>>1,i>>1);
    }
    map<ull,int>mp;
    int calcnode(int k){
    	int nw=0,pw=1;k-=4;
    	while(k--)Line(E[nw],E[pw]),nw^=1,pw^=1;
    	return E[nw]->calc();
    }
    int calc(){
    	ntr->Pre(),E[0]->Pre(ntr->n);
    	fp(u,0,ntr->n-1)gg(ntr->to[u])E[0]->Add(u+1,v+1),E[0]->Add(v+1,u+1);
    	int res=calcnode(k);
    	fp(i,1,(1<<ntr->n)-2){
    		int p=ntr->ck(i);
    		((~p)&&mp.find(ntr->f[p])!=mp.end())?res=dec(res,mp[ntr->f[p]]):0;
    	}
    	return mp[ntr->mdzz]=res;
    }
    int g[N],las[15],leaf[15],f[N][15];bool L[15];
    void dfs(int u,int fa){
    	int sz=0;
    	go(u)v!=fa?(dfs(v,u),++sz):0;
    	fp(i,0,ntr->n-1){
    		if(L[i])continue;
    		if(sz<pc[ntr->to[i]]){f[u][i]=0;continue;}
    		for(int j=ntr->to[i];j;j=(j-1)&ntr->to[i])g[j]=0;
    		g[0]=1;
    		for(int j=T->head[u],v=T->e[j].v;j;j=T->e[j].nx,v=T->e[j].v)if(v!=fa)
    			for(int k=ntr->to[i];k;k=(k-1)&ntr->to[i])
    				for(int p=k;p;p-=p&-p)
    					g[k]=add(g[k],1ll*g[k^(p&-p)]*f[v][lg[p&-p]]%P);
    		f[u][i]=1ll*g[ntr->to[i]]*ntr->jc[i]%P*C[sz-pc[ntr->to[i]]][leaf[i]]%P*fac[leaf[i]]%P;
    	}
    }
    int calctimes(){
    	fp(i,0,ntr->n-1)las[i]=ntr->to[i],leaf[i]=L[i]=0;
    	fp(u,0,ntr->n-1)gg(ntr->to[u])ntr->siz[v]==1?(++leaf[u],ntr->to[u]^=(1<<v)):0;
    	fp(i,0,ntr->n-1)ntr->siz[i]==1?L[i]=true:0;
    	dfs(1,0);
    	fp(u,0,ntr->n-1)ntr->to[u]=las[u];
    	int res=0;
    	fp(i,1,n)res=add(res,f[i][0]);
    	return res;
    }
    int fa[25];
    int st[N<<1],top;set<ull>vis;
    void solve(int x,int c,int sp,int lim){
    	if(x==(lim-1)*2+1){
    		int now=0,tot=0;ntr->clr();
    		fp(i,1,x-1)st[i]==1?(ntr->to[now]|=(1<<(++tot)),fa[tot]=now,now=tot):now=fa[now];
    		ntr->n=lim,ntr->Pre();
    		if(vis.find(ntr->mdzz)!=vis.end())return;
    		vis.insert(ntr->mdzz);
    		ans=add(ans,1ll*calctimes()*calc()%P);
    		return;
    	}
    	if(c)st[x]=-1,solve(x+1,c-1,sp,lim);
    	if(sp<lim-1)st[x]=1,solve(x+1,c+1,sp+1,lim);
    }
    void spj(){
    	switch(k){
    		case 1:printf("%d
    ",n-1);break;
    		case 2:{
    			fp(i,1,n)ans=add(ans,1ll*deg[i]*(deg[i]-1)>>1);
    			printf("%d
    ",ans);
    			break;
    		}
    		case 3:{
    			for(int i=2;i<T->tot;i+=2){
    				int d=deg[T->e[i].v]+deg[T->e[i^1].v]-2;
    				ans=add(ans,1ll*d*(d-1)>>1);
    			}
    			printf("%d
    ",ans);
    			break;
    		}
    		case 4:printf("%d
    ",T->calc());break;
    		default:{
    			fp(i,1,k+1)solve(1,0,0,i);
    			printf("%d
    ",ans);
    			break;
    		}
    	}
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	T=&pool[0],E[0]=&pool[1],E[1]=&pool[2],ntr=&qwq;
    	n=read(),k=read(),T->Pre(n);
    	for(R int i=1,u,v;i<n;++i)u=read(),v=read(),++deg[u],++deg[v],T->Add(u,v),T->Add(v,u);
    	fp(i,2,N-1)lg[i]=lg[i>>1]+1;
    	fp(i,1,N-1)pc[i]=pc[i>>1]+(i&1);
    	fp(i,0,N-1)C[i][0]=1;fac[0]=1;
    	fp(i,1,14)fac[i]=mul(fac[i-1],i);
    	fp(i,1,14)fp(j,1,i)C[i][j]=add(C[i-1][j],C[i-1][j-1]);
    	fp(i,15,N-1)fp(j,1,14)C[i][j]=add(C[i-1][j],C[i-1][j-1]);
    	spj();
    	return 0;
    }
    
  • 相关阅读:
    Vasya and Multisets
    tp5.1 输出json格式字符串被转义
    异步委托(实现多线程的方式)
    模糊查询(like)
    webService
    EL表达式
    远程登陆服务器(window系统)
    output引用类型
    存储过程的定义、修改和删除
    leetcode刷题笔记一百六十二题 寻求峰值
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10566232.html
Copyright © 2011-2022 走看看