hdu5555

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int M=1010,mod=105225319;
const long long modll=mod;
struct node{
 int l,r,v;
}p[M];
bool operator < (const node &a,const node &b)
{
    return a.v<b.v;
}
int cas,n,m,cnt[3],id[3][15],state[2][M],vis[M];
int dp[2][1024];
void clear(const int &X)
{
    memset(dp[X],0,sizeof(dp[X]));
    memset(state[X],0,sizeof(state[X]));
    cnt[X]=cnt[2]=0;
}
int merge( const int &a , const int &b , const int &x , const int &y , int &t ){
int ret = 0, l = 1, r = 1;t = 0;
while( l <= cnt[a] && p[id[a][l]].r < y )
ret |= state[a][id[a][l++]], t ++;
while( l <= cnt[a] && r <= cnt[b] ){
if( p[id[a][l]].r < p[id[b][r]].r )
id[x][++cnt[x]] = id[a][l++];
else
id[x][++cnt[x]] = id[b][r++];
}
while( l <= cnt[a] )
id[x][++cnt[x]] = id[a][l++];
while( r <= cnt[b] )
id[x][++cnt[x]] = id[b][r++];
for( int i = cnt[x] , tt = 1 ; i ; i -- , tt <<= 1 )
state[x][id[x][i]] = tt;
return ret;
}
long long work(){
int zero,t,st=1,now=0,bef=1;
clear(now);
dp[0][0]=1;
for(int i=1;i<=n;i++){
now^=1;
        bef^=1;
clear(now);
while(st<=m&&p[st].l==i)
id[2][++cnt[2]]=st++;
zero=merge(bef,2,now,i,t);
for(int nj,fj,j=zero,up=1<<cnt[bef] ; j < up ; j ++ ){
fj = 0;
if( !dp[bef][j] )
continue;
for( int k = 1 ; k <= cnt[bef] ; k ++ )
if( j & state[bef][id[bef][k]] )
fj |= state[now][id[bef][k]];
for( int k = 0 ; k <= cnt[now] ; k ++ ){
if( k && p[id[now][k]].l < i && ( j & state[bef][id[now][k]] ) )
continue;
nj = fj | state[now][id[now][k]];
dp[now][nj] += dp[bef][j];
if( dp[now][nj] >= mod )
dp[now][nj] -= mod;
}
}
}
return (long long)dp[now][(1<<cnt[now])-1];
}


int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(vis,0,sizeof(vis));
        long long ep=0,ans=1,flag=0;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&p[i].l);
        }
        for(int i=0;i<n;i++)
        {
            scanf("%d",&p[i].r);
            if(p[i].l!=1&&p[i].r!=n)
            {
                for(int j=p[i].l;j<=p[i].r;j++)
                {
                    vis[j]++;
                    if(vis[j]>10) flag=1;
                }
                p[i].v=p[i].l<<10|p[i].r;
            }
        }
        if(flag){
         printf("Case #%d: 0\n",T);
         continue;
        }
        m=0;
        for(int i=1;i<=n;i++)
        {
            if(p[i].l==1&&p[i].r==n)
            {
                ep++;
                ans=ans*ep%modll;
            }
            else
            {
                p[++m]=p[i];
            }
        }
        sort(p+1,p+m+1);
        printf("Case #%d: %I64d\n",T,work()*ans%modll);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值