1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
| #include<vector> #include<cstdio> #include<cstring> #include<algorithm> using namespace std;
const int N=310,M=3000,MOD=1e9+7;
inline int Add(const int &a,const int &b){return a+b>=MOD? a+b-MOD:a+b;} inline int Sub(const int &a,const int &b){return a-b<0? a-b+MOD:a-b;} inline int Mul(const int &a,const int &b){return 1ll*a*b%MOD;} inline int Pow(int a,int b){int r=1;while(b){if(b&1)r=Mul(r,a);a=Mul(a,a),b>>=1;}return r;}
int n,lef,rig,nbmap,nvis,beg; int cap[N][2],bmap[N][N],cmap[M][2]; int dp[M][N],vis[M][N]; vector<int> uni;
int DP(int le,int ri,int hi){ if(le>ri) return 1; if(!bmap[le][ri]) bmap[le][ri]=++nbmap,cmap[nbmap][0]=le,cmap[nbmap][1]=ri; int u=bmap[le][ri],h=hi-beg; if(h<0) return 0; if(vis[u][h]==nvis) return dp[u][h]; dp[u][h]=0,vis[u][h]=nvis; int mid=(le+ri)>>1; dp[u][h]=DP(le,ri,hi-1); for(int i=mid-1;i<=mid+1;i++){ int bet=(i-le)-(ri-i); if(bet<-2 || bet>2 || i<le || i>ri || hi<cap[i][0] || hi>cap[i][1]) continue; int nowh=min(hi,cap[i][1]); dp[u][h]=Add(dp[u][h],Mul(DP(le,i-1,nowh),DP(i+1,ri,nowh-1))); } return dp[u][h]; } inline int Ri(){ register int a=0,c=getchar(); while(c<'0' || '9'<c) c=getchar(); while('0'<=c && c<='9') a=(a<<1)+(a<<3)+c-'0',c=getchar(); return a; } int prep[N],sufp[N],fac[N],ifac[N]; int Poly(int u,int x){ int ret=0; prep[0]=sufp[n+2]=1; for(int i=1;i<=n+1;i++) prep[i]=Mul(prep[i-1],Sub(x,i)); for(int i=n+1;i>=1;i--) sufp[i]=Mul(sufp[i+1],Sub(x,i)); for(int i=1;i<=n+1;i++){ int tim1=Mul(dp[u][i],Mul(prep[i-1],sufp[i+1])); int tim2=Mul((n+1-i)&1? MOD-1:1,Mul(ifac[i-1],ifac[n+1-i])); ret=Add(ret,Mul(tim1,tim2)); } return ret; } void Use(int le,int ri){ if(le>ri) return; if(bmap[le][ri]) return; nbmap++; cmap[nbmap][0]=le,cmap[nbmap][1]=ri; bmap[le][ri]=nbmap; int mid=(le+ri)>>1; for(int i=mid-1;i<=mid+1;i++){ int bet=(i-le)-(ri-i); if(bet<-2 || bet>2 || i<le || i>ri) continue; Use(le,i-1);Use(i+1,ri); } } int main(){ freopen("robot.in","r",stdin); freopen("robot.out","w",stdout); fac[0]=1; for(int i=1;i<N;i++) fac[i]=Mul(fac[i-1],i); ifac[N-1]=Pow(fac[N-1],MOD-2); for(int i=N-2;i>=0;i--) ifac[i]=Mul(ifac[i+1],i+1); n=Ri(); for(int i=1;i<=n;i++){ cap[i][0]=Ri(),cap[i][1]=Ri(); uni.push_back(cap[i][0]); uni.push_back(cap[i][1]+1); } uni.push_back(1); sort(uni.begin(),uni.end()); uni.erase(unique(uni.begin(),uni.end()),uni.end()); Use(1,n); for(int i=1;i<(int)uni.size();i++){ lef=uni[i-1],rig=uni[i]-1; beg=lef-1; nvis++; for(int u=1;u<=nbmap;u++) for(int j=lef;j<=rig && j<=lef+n;j++) DP(cmap[u][0],cmap[u][1],j); for(int u=1;u<=nbmap;u++) if(rig<=lef+n) dp[u][0]=dp[u][rig-beg],vis[u][0]=nvis+1; else{ if(!dp[u][n+1]) dp[u][0]=dp[u][n+1],vis[u][0]=nvis+1; else{ dp[u][0]=Poly(u,rig-beg); vis[u][0]=nvis+1; } } } printf("%d\n",dp[bmap[1][n]][0]); return 0; }
|