NOIP前做了几道POI,现在终于能在BZOJ上提交了…

交上去最后几个点WA,看了数据发现p=0的特判错了…

p=0,1时特判

p=2时构造两种情况判断

p=3时不考虑1的座位进行DP

可以发现对于i+1的位置安排,我们只关心i-2,i-1,i的相对顺序以及它们的相邻、边界情况

所以设f[i][j][S1][S2]表示已经安排了前i个人的座位,i-2,i-1,i的顺序为j,是否有人在两端点为S1,是否有人相邻为S2的方案数

答案最后再除以n

这样复杂度有点飞…

#include<cstdio>
typedef long long ll;
const int N=1000010,P=1000000007;
int n,m,p,i,j,S1,S2,ans;bool ban[N][7];//0:-3 3:0 6:3
inline int abs(int x){return x>0?x:-x;}
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
namespace Subtask2{
int a[N];
bool flag;
inline void Main(){
if(n&1){
flag=1;
for(a[j=1]=1,i=2;i<n;i+=2)a[++j]=i;
for(i=n;i>2;i-=2)a[++j]=i;
for(i=1;i<n;i++)if(ban[a[i]][a[i+1]-a[i]+3])flag=0;
if(ban[a[n]][a[1]-a[n]+3])flag=0;
if(flag)ans++;
flag=1;
for(a[j=0],i=1;i<=n;i+=2)a[++j]=i;
for(i=n-1;i;i-=2)a[++j]=i;
for(i=1;i<n;i++)if(ban[a[i]][a[i+1]-a[i]+3])flag=0;
if(ban[a[n]][a[1]-a[n]+3])flag=0;
if(flag)ans++;
}else{
flag=1;
for(a[j=1]=1,i=2;i<=n;i+=2)a[++j]=i;
for(i=n-1;i>2;i-=2)a[++j]=i;
for(i=1;i<n;i++)if(ban[a[i]][a[i+1]-a[i]+3])flag=0;
if(ban[a[n]][a[1]-a[n]+3])flag=0;
if(flag)ans++;
flag=1;
for(a[j=0],i=1;i<n;i+=2)a[++j]=i;
for(i=n;i;i-=2)a[++j]=i;
for(i=1;i<n;i++)if(ban[a[i]][a[i+1]-a[i]+3])flag=0;
if(ban[a[n]][a[1]-a[n]+3])flag=0;
if(flag)ans++;
}
}
}
namespace Subtask3{
struct E{int nxt,j,S1,S2,l,r;/*1:i-2 2:i-1 3:i*/}e[200];
int g[6][4][4],ed,k;
int loc[6][3]={{1,2,3},{1,3,2},{2,1,3},{2,3,1},{3,1,2},{3,2,1}};
int hash[500],tmp[10],r,pos[3],pl[5];
int f[2][6][4][4];
bool isl,isr,cl1,cl2;
inline ll pow(ll a,int b){ll t=1;for(;b;b>>=1,a=a*a%P)if(b&1)t=t*a%P;return t;}
inline void add(int l,int r){
int nj=0,i,t=0,p;
for(i=l;i<=r;i++)if(tmp[i]>=2)pl[++t]=i,(nj*=10)+=tmp[i];
e[++ed].j=hash[nj];
e[ed].S1=((pl[1]==l)<<1)|(pl[3]==r);
e[ed].S2=((pl[1]+2>=pl[2])<<1)|(pl[2]+2>=pl[3]);
for(t=0,i=l;i<=r;i++)if(tmp[i]){
pl[++t]=i;
if(tmp[i]==4)p=t;
}
if(p>1&&pl[p-1]+2>=pl[p])e[ed].l=tmp[pl[p-1]];
if(p<4&&pl[p]+2>=pl[p+1])e[ed].r=tmp[pl[p+1]];
e[ed].nxt=g[j][S1][S2];
g[j][S1][S2]=ed;
}
inline void init(){
hash[243]=1;hash[324]=2;hash[342]=3;hash[423]=4;hash[432]=5;
for(j=0;j<6;j++)for(S1=0;S1<4;S1++)for(S2=0;S2<4;S2++){
isl=S1>>1&1,isr=S1&1,cl1=S2>>1&1,cl2=S2&1;
tmp[r=0]=0;
if(!isl)tmp[++r]=0;
tmp[pos[1]=++r]=loc[j][0];
tmp[++r]=0;if(!cl1)tmp[++r]=0;
tmp[pos[2]=++r]=loc[j][1];
tmp[++r]=0;if(!cl2)tmp[++r]=0;
tmp[++r]=loc[j][2];
if(!isr)tmp[++r]=0;
if(isl&&isr)tmp[0]=4,add(0,r),tmp[0]=0,tmp[r+1]=4,add(1,r+1),tmp[r+1]=0;
if(cl1)tmp[pos[1]+1]=4,add(1,r),tmp[pos[1]+1]=0;
if(cl2)tmp[pos[2]+1]=4,add(1,r),tmp[pos[2]+1]=0;
}
}
inline void Main(){
init();
for(j=0;j<6;j++)f[1][j][3][3]=1;
for(i=3;i<n;i++){
for(j=0;j<6;j++)for(S1=0;S1<4;S1++)for(S2=0;S2<4;S2++)f[i&1^1][j][S1][S2]=0;
for(j=0;j<6;j++)for(S1=0;S1<4;S1++)for(S2=0;S2<4;S2++)if(f[i&1][j][S1][S2])for(k=g[j][S1][S2];k;k=e[k].nxt){
if(e[k].l==1)if(ban[i-2][6])continue;
if(e[k].r==1)if(ban[i+1][0])continue;
if(S2>>1&1){
if(loc[j][0]==1&&ban[i-2][loc[j][1]+2]&&e[k].l!=1)continue;
if(loc[j][1]==1&&ban[i+loc[j][0]-3][4-loc[j][0]]&&e[k].r!=1)continue;
}
if(S2&1){
if(loc[j][1]==1&&ban[i-2][loc[j][2]+2]&&e[k].l!=1)continue;
if(loc[j][2]==1&&ban[i+loc[j][1]-3][4-loc[j][1]]&&e[k].r!=1)continue;
}
if(S1==3){
if(loc[j][0]==1&&ban[i+loc[j][2]-3][4-loc[j][2]]&&e[k].l&&e[k].r)continue;
if(loc[j][2]==1&&ban[i-2][loc[j][0]+2]&&e[k].l&&e[k].r)continue;
}
if(S1&1){
if(loc[j][2]==1&&ban[i-2][6]&&(!e[k].l||!e[k].r))continue;
}
if(S1>>1&1){
if(loc[j][0]==1&&ban[i+1][0]&&(!e[k].l||!e[k].r))continue;
}
(f[i&1^1][e[k].j][e[k].S1][e[k].S2]+=f[i&1][j][S1][S2])%=P;
}
}
for(j=0;j<6;j++)for(S1=0;S1<4;S1++)for(S2=0;S2<4;S2++)if(f[n&1][j][S1][S2]){
if(S2>>1&1)if(ban[n+loc[j][0]-3][loc[j][1]-loc[j][0]+3])continue;
if(S2&1)if(ban[n+loc[j][1]-3][loc[j][2]-loc[j][1]+3])continue;
if(S1==3)if(ban[n+loc[j][2]-3][loc[j][0]-loc[j][2]+3])continue;
(ans+=f[n&1][j][S1][S2])%=P;
}
ans=(ll)ans*pow(n,P-2)%P;
}
}
int main(){
read(n),read(m),read(p);
if(n==1)return puts("1"),0;
if(p==0)return puts("0"),0;
if(n==2)return puts(m?"0":"1"),0;
if(p==1)return puts("0"),0;
while(m--){
read(i),read(j);
if(abs(i-j)<=p)ban[i][j-i+3]=1;
}
if(p==2)Subtask2::Main();else Subtask3::Main();
return printf("%d",ans),0;
}

  

BZOJ3746 : [POI2015]Czarnoksiężnicy okrągłego stołu的更多相关文章

  1. BZOJ #3746: [POI2015]Czarnoksiężnicy okrągłego stołu 动态规划

    转载请注明出处:http://www.cnblogs.com/TSHugh/p/8823423.html 读完题就会发现p=0.1的情况以及n=1.2的情况都可以直接判掉,而p=2的时候也可以直接构造 ...

  2. BZOJ 4276: [ONTAK2015]Bajtman i Okrągły Robin [线段树优化建边]

    4276: [ONTAK2015]Bajtman i Okrągły Robin 题意:\(n \le 5000\)个区间\(l,r\le 5000\),每个区间可以选一个点得到val[i]的价值,每 ...

  3. [ONTAK2015]Bajtman i Okrągły Robin

    bzoj 4276: [ONTAK2015]Bajtman i Okrągły Robin Time Limit: 40 Sec  Memory Limit: 256 MB Description 有 ...

  4. Bajtman i Okrągły Robin

    Bajtman i Okrągły Robin 题目描述 你是一个保安,你发现有n个强盗,其中第i个强盗会在[a[i],a[i]+1],[a[i]+1,a[i]+2],...,[b[i]-1,b[i] ...

  5. 4276: [ONTAK2015]Bajtman i Okrągły Robin

    4276: [ONTAK2015]Bajtman i Okrągły Robin Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 345  Solved ...

  6. 【BZOJ4276】[ONTAK2015]Bajtman i Okrągły Robin 线段树优化建图+费用流

    [BZOJ4276][ONTAK2015]Bajtman i Okrągły Robin Description 有n个强盗,其中第i个强盗会在[a[i],a[i]+1],[a[i]+1,a[i]+2 ...

  7. BZOJ_4276_[ONTAK2015]Bajtman i Okrągły Robin_线段树优化建图+最大费用最大流

    BZOJ_4276_[ONTAK2015]Bajtman i Okrągły Robin_线段树优化建图+最大费用最大流 Description 有n个强盗,其中第i个强盗会在[a[i],a[i]+1 ...

  8. BZOJ4276 : [ONTAK2015]Bajtman i Okrągły Robin

    建立线段树, S向每个叶子连边,容量1,费用0. 孩子向父亲连边,容量inf,费用0. 每个强盗向T连边,容量1,费用为c[i]. 对应区间内的点向每个强盗,容量1,费用0. 求最大费用流即可. #i ...

  9. BZOJ 4276: [ONTAK2015]Bajtman i Okrągły Robin

    最大权值匹配,贪心匈牙利即可. 检查一些人是否能被全部抓住可以采用左端点排序,右端点优先队列处理. By:大奕哥 #include<bits/stdc++.h> using namespa ...

随机推荐

  1. macbook air 安装win7双系统

    转自: http://jingyan.baidu.com/article/6d704a13f99f1a28da51ca49.html 1)遇到“No bootable device-insert bo ...

  2. InnoDB主键设计

    InnoDB是clustered-index table,因此对于InnoDB而言,主键具有特殊意义. 可以通过主键直接定位到对应的某一数据行记录的物理位置,主键索引指向对应行记录,其他索引则都指向主 ...

  3. css 中的度量单位

    px 相对长度单位.像素(Pixel). 像素是相对于显示器屏幕分辨率而言的.譬如,WONDOWS的用户所使用的分辨率一般是96像素/英寸.而MAC的用户所使用的分辨率一般是72像素/英寸. em 相 ...

  4. Maven发布web项目到tomcat

    在java开发中经常要引入很多第三方jar包:然而无论是java web开发还是其他java项目的开发经常会由于缺少依赖包引来一些不必要的异常.常常也是因为这样的原因导致许多简单的缺包和版本问题耗费大 ...

  5. Java读写文件的几种方式

    自工作以后好久没有整理Java的基础知识了.趁有时间,整理一下Java文件操作的几种方式.无论哪种编程语言,文件读写操作时避免不了的一件事情,Java也不例外.Java读写文件一般是通过字节.字符和行 ...

  6. Python多线程(2)——线程同步机制

    本文介绍Python中的线程同步对象,主要涉及 thread 和 threading 模块. threading 模块提供的线程同步原语包括:Lock.RLock.Condition.Event.Se ...

  7. codeforces 479C Exams 解题报告

    题目链接:http://codeforces.com/problemset/problem/479/C 题目意思:简单来说,就是有个人需要通过 n 门考试,每场考试他可以选择ai, bi 这其中一个时 ...

  8. HDU 5754 Life Winner Bo (各种博弈) 2016杭电多校联合第三场

    题目:传送门 题意:一个国际象棋棋盘,有四种棋子,从(n,m)走到(1,1),走到(1,1)的人赢,先手赢输出B,后手赢输出G,平局输出D. 题解:先把从(n,m)走到(1,1)看做是从(1,1)走到 ...

  9. 开源混淆工具ProGuard配置详解及配置实例

    ProGuard的作用:   1.创建紧凑的代码文档是为了更快的网络传输,快速装载和更小的内存占用. 2.创建的程序和程序库很难使用反向工程. 3.所以它能删除来自源文件中的没有调用的代码 4.充分利 ...

  10. AU版有锁机的福利,704越狱彻底解决+86问题,完美IM/FT,重启不掉APN设置

    http://bbs.25pp.com/thread-172881-1-1.html 串号99的是au版 串号013的是sb版 44050   AU为 找到咱们SB版的文件,为44020 http:/ ...