Codeforces Round #184 (Div. 2) D、E
来源:互联网 发布:java sql 批处理 编辑:程序博客网 时间:2024/03/29 14:04
D题根据题目描述,图中只能存在两类边:第一类,对于所有的 i (1<=i<n) 都存在边 i-->i+1;第二类,对于 i 可以存在边 i-->i+k+1 (i>=1 && i+k+1<=n),若边 x-->x+k+1 存在,则不能存在这样的边 y-->y+k+1 (y>=x+k+1)。弄清楚这些后,剩下的就是常规的排列组合了。代码如下(比较挫):
#include<stdio.h>#include<iostream>using namespace std;#define MOD 1000000007bool Is[1000010];long long quickpow(long long i,long long x);long long run(long long L,long long R,long long K);int main(){ int n,m,k,l,r,L,R; bool flag=true; long long ans; l=r=0; scanf("%d%d%d",&n,&m,&k); for(int i=0;i<m;i++) { int u,v; scanf("%d%d",&u,&v); if(flag && v!=u+1) { if(v-u-k!=1) { flag=false; continue; } Is[u]=true; if(l==0) l=r=u; else r=u; } } if(flag==false) { printf("0\n"); return 0; } if(l==0) { if(n-(k+1)*2>=0) { ans=quickpow(k,2); ans=((ans*2)%MOD+((n-(k+1)*2)*ans)%MOD)%MOD; printf("%lld\n",ans); } else if(n-k-1>=0) { ans=quickpow(n-k-1,2); printf("%lld\n",ans); } else printf("1\n"); return 0; } if(r-l>k) printf("0\n"); else { L=max(r-k,1),R=min(l+k,n-k-1); ans=run(L,R,k); printf("%lld\n",ans); } return 0;}long long run(long long L,long long R,long long K){ long long rt,cnt; cnt=0; for(int i=L;i<=L+K && i<=R;i++) if(Is[i]==false) cnt++; rt=quickpow(cnt,2); for(int i=L+1;i<=R-K;i++) { if(Is[i-1]==false) cnt--; if(Is[i+K]==false) { rt=(rt+quickpow(cnt,2))%MOD; cnt++; } } return rt;}long long quickpow(long long i,long long x){ if(i==0) return 1; if(i==1) return x; if(i==2) return x*x; long long rt=quickpow(i/2,x); if(i%2==0) rt=(rt*rt)%MOD; else rt=((rt*rt)%MOD*x)%MOD; return rt;}
E题,首先找出字符串中所有回文子串的中心,将对应位置的字母替换为 1 ,其余字母替换为 0 。 比如 abacaba 对应的01串为 0101010 。那么问题就转化为:两人轮流取 1 ,最后不能取者,败。取 1 的规则如下:每次至少取1个,如果取走的位置的左右有 1 则也同时取走。被0相互分割的 1 是相互独立的。这显然是一个无偏博弈,用SG函数就可以解决了。
#include<stdio.h>#include<iostream>#include<string.h>using namespace std;#define MAXN 5010int SG[MAXN],F[MAXN],len,ans;char str[MAXN];void Init();bool check(int n);int main(){ scanf("%s",str); len=strlen(str); Init(); for(int i=1;i<len-1;) { if(str[i-1]==str[i+1]) { int num=1; for(int j=i+1;j<len-1;j++) if(str[j-1]!=str[j+1]) break; else num++; ans^=SG[num]; i+=num; } else i++; } if(ans==0) printf("Second\n"); else { for(int i=1;i<len-1;i++) if(str[i-1]==str[i+1] && check(i)) { printf("First\n%d\n",i+1); break; } } return 0;}void Init(){ for(int i=1;i<=len;i++) { for(int j=1;j<=(i+1)/2;j++) { F[SG[max(j-2,0)]^SG[max(i-j-1,0)]]=i; } while(F[SG[i]]==i) SG[i]++; }}bool check(int n){ int rt,i,l,r; rt=ans; l=r=0; for(i=n-1;i>0;i--) if(str[i-1]==str[i+1]) l++; else break; for(i=n+1;i<len-1;i++) if(str[i-1]==str[i+1]) r++; else break; rt=rt^SG[1+l+r]^SG[max(l-1,0)]^SG[max(r-1,0)]; return rt==0;}
- Codeforces Round #184 (Div. 2) D、E
- Codeforces Round #283 (Div. 2) D,E
- Codeforces Round #306 (Div. 2) D-E
- Codeforces Round #345 (Div. 2) D,E
- Codeforces Round #368 (Div. 2) D &E
- Codeforces Round #443 (Div. 2) D,E
- Codeforces Round #186 (Div. 2)A、B、C、D、E
- Codeforces Round #237 (Div. 2) E. Maze 1D
- Codeforces Round #258 (Div. 2)-(A,B,C,D,E)
- Codeforces Round #261 (Div. 2) A,B,C,D,E
- Codeforces Round #263 (Div. 2) A,B,C,D,E
- Codeforces Round #264 (Div. 2) A,B,C,D,E
- Codeforces Round #274 (Div. 2) 解题报告 (C D E)
- Codeforces Round #277 (Div. 2) A,B,C,D,E
- Codeforces Round #280 (Div. 2 A,B,C,D,E)
- Codeforces Round #287 (Div. 2) A、B、C、D、E
- Codeforces Round #287 (Div. 2)A,B,C,D,E
- Codeforces Round #288 (Div. 2) A,B,C,D,E
- SI,DI
- Java霓虹灯的循环显示
- 网络安全热门资料 精品工具(转载)
- 【珍藏】 2012Android开发热门资料(110个)(转载)
- Qt堆栈窗口StackedLayout
- Codeforces Round #184 (Div. 2) D、E
- 我们要掌控什么——承认失败要趁早
- shell脚本echo的换行操作
- 实现二叉树
- 心情
- 心情
- CSS取消滚动条一直显示
- c++ static
- ubuntu12安装JDK6