zoukankan      html  css  js  c++  java
  • uoj#214. 【UNR #1】合唱队形

    min-max 容斥 (m)大了直接爆搜 (m)小的话就状压DP
    先开小数组 dp两维开数组时还弄反了...

    #include<bits/stdc++.h>
    using namespace std;
    #define fp(i,l,r) for(register int (i)=(l);i<=(r);++(i))
    #define fd(i,l,r) for(register int (i)=(l);i>=(r);--(i))
    #define fe(i,u) for(register int (i)=front[(u)];(i);(i)=e[(i)].next)
    #define mem(a) memset((a),0,sizeof (a))
    #define O(x) cerr<<#x<<':'<<x<<endl
    #define int long long
    inline int read(){
    	int 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 x*f;
    }
    void wr(int x){
    	if(x<0)putchar('-'),x=-x;
    	if(x>=10)wr(x/10);
    	putchar('0'+x%10);
    }
    const int mod=998244353;
    inline void tmod(int &x){x%=mod;}
    inline void rmod(int &x){x+=x>>31&mod;}
    inline int qpow(int a,int b){
    	int res=1;a%=mod;
    	for(;b;b>>=1,tmod(a*=a))
    		if(b&1)tmod(res*=a);
    	return res;
    }
    inline int ginv(int x){return qpow(x,mod-2);}
    bool book[35][35],Can[35];
    int n,m,dp[2][1<<10][910],a[1<<11],tot,g[1001],ans,buc[33][33];
    char str[35];
    void dfs(int d,int st,bool sgn){
    	if(!d){
    		if(sgn)rmod(ans-=g[st]);else rmod(ans+=g[st]-mod);
    		return;
    	}
    	dfs(d-1,st,sgn);
    	if(Can[d]){
    		fp(i,1,m)if(!buc[d+i-1][str[i]]++)++st;
    		dfs(d-1,st,!sgn);
    		fp(i,1,m)if(!--buc[d+i-1][str[i]])--st;
    	}
    }
    inline void solve1(){
    	dfs(n-m+1,0,1);
    	printf("%lld
    ",ans*tot%mod);
    }
    inline void solve2(){
    	int S=(1<<m)-1,cur=0;
    	fp(i,1,m)a[1<<i-1]=1<<str[i];
    	fp(i,1,S)a[i]=a[i^(i&-i)]|(a[i&-i]);
    	fp(i,1,S)a[i]=__builtin_popcount(a[i]);S>>=1;
    	mem(dp[0]);dp[0][0][0]=mod-1;
    	fp(i,1,n){
    		cur^=1;mem(dp[cur]);
    		fp(j,0,S)
    			fp(k,0,tot)if(dp[cur^1][j][k]){
    			const int t=j<<1,p=dp[cur^1][j][k];
    			rmod(dp[cur][t&S][k+a[t]]+=p-mod);
    			if(Can[i])rmod(dp[cur][(t|1)&S][k+a[t|1]]-=p);
    		}
    	}
    	fp(i,0,S)fp(j,0,tot)
    		tmod(ans+=g[j]*dp[cur][i][j]);
    	printf("%lld
    ",ans*tot%mod);
    }
    inline void solve(){
    	mem(book);mem(Can);mem(a);tot=ans=0;
    	n=read();m=read();
    	fp(i,1,n){
    		scanf("%s",str+1);int tt=strlen(str+1);tot+=tt;
    		fp(j,1,tt)book[i][str[j]-'a']=1;
    	}
    	scanf("%s",str+1);fp(i,1,m)str[i]-='a';
    	bool fl=0;
    	fp(i,1,n-m+1){
    		fp(j,1,m)if(!book[i+j-1][str[j]])goto ss;
    		Can[i]=1;fl=1;
    	    ss:;
    	}
    	if(!fl){puts("-1");return;}
    	if(m<=11)solve2();
    	else solve1();
    }
    main(){
    	fp(i,1,1000)rmod(g[i]=ginv(i)+g[i-1]-mod);
    	int tt=read();
    	while(tt--)solve();
    	return 0;
    }
    
  • 相关阅读:
    smarty对网页性能的影响
    php-fpm正在生成页面时,浏览器刷新后,php-fpm会退出吗?
    为什么日志记录到别的目录了?
    一个空格引发的bug
    linux内核--页高速缓存
    radix树
    linux内核--用户态内存管理
    linux内核--内核内存管理
    linux内核--软中断与tasklet
    linux内核--几个上下文(context)
  • 原文地址:https://www.cnblogs.com/WinterSpell/p/13272242.html
Copyright © 2011-2022 走看看