期望得分:100+60+100=260

实际得分:0+60+40=100

设图中有m个环,每个环有si条边,有k条边不在环中

ans= (2^s1 -2)*( 2^s2 -2)* (2^s3 -2)…… *( 2^sm -2)* 2^k

(环上的边只有两种可能形成环)

找环好找,怎么找树?

一种方法是tarjan找出所有的环,总边数-环的边数=树的边数

std用了拓扑排序

考场上忘了树的情况,爆零了。

注意:n个点n条边是环套树森林

#include<cstdio>
#define N 100001
using namespace std;
typedef long long LL;
int to[N],d[N],q[N],sum;
const int mod=1e9+;
LL pow(LL a,int b)
{
LL res=;
for(;b;b>>=,a=a*a%mod)
if(b&) res=res*a%mod;
return res;
}
void dfs(int x)
{
sum++;
d[x]=;
if(d[to[x]]) dfs(to[x]);
}
int main()
{
freopen("road.in","r",stdin);
freopen("road.out","w",stdout);
int n;
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&to[i]),d[to[i]]++;
int h=,t=;
for(int i=;i<=n;i++)
if(!d[i]) q[++t]=i;
while(h<=t)
{
if(!(--d[to[q[h]]])) q[++t]=to[q[h]];
++h;
}
LL ans=pow(,t);
for(int i=;i<=n;i++)
if(d[i])
{
sum=;
dfs(i);
ans=ans*(pow(,sum)-)%mod;
}
printf("%I64d",ans);
}

本题60分是经典的n^2 LCS问题

第一个串长1000,第二个串长1e6

很显然枚举只能枚举第一个串

n^2 中是dp[i][j] 表示第一个字符串的前i个字符 与 第二个字符串的前j个字符 的 最长公共子串长度

它的优化是:

dp[i][j] 表示 第一个字符串的前i个字符,与 第二个字符串匹配了长为j的最长公共子串,第j个字符在第二个字符串中的最左下标

这样最后倒序枚举 j,当dp[len1][j]<=len2 时,输出j,return 0

如何转移?

考虑顺推

第一个字符串的第i+1 位如果不发生匹配,那么dp[i+1][j]=min(dp[i+1][j],dp[i][j])

第i+1位如果发生匹配,那么dp[i+1][j+1]=min(dp[i+1][j+1],nxt[dp[i][j]+1][s1[i+1]])

其中nxt[i][j]表示在第二个字符串中,第i位及后面最早出现字符j的位置

#include<cstdio>
#include<cstring>
#include<algorithm> using namespace std; #define N 1001
#define M 1000001 char s1[N],s2[M];
int nxt[M][],dp[N+][N]; int main()
{
freopen("lcs.in","r",stdin);
freopen("lcs.out","w",stdout);
scanf("%s%s",s1+,s2+);
int len1=strlen(s1+),len2=strlen(s2+);
for(int i=;i<;i++) nxt[len2+][i]=len2+;
for(int i=len2;i>=;i--)
for(int j=;j<;j++)
if(s2[i]-'a'==j) nxt[i][j]=i;
else nxt[i][j]=nxt[i+][j];
memset(dp,,sizeof(dp));
for(int i=;i<=len1;i++) dp[i][]=;
for(int i=;i<len1;i++)
for(int j=;j<=i && dp[i][j]<=len2;j++)
{
dp[i+][j]=min(dp[i+][j],dp[i][j]);
if(j<len1) dp[i+][j+]=min(dp[i+][j+],nxt[dp[i][j]+][s1[i+]-'a']);
}
for(int i=len1;i>=;i--)
if(dp[len1][i]<=len2) { printf("%d\n",i); return ; }
}

60分暴力:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 1001
using namespace std;
char s1[N],s2[N];
int l1,l2;
int dp[N][N];
int main()
{
freopen("lcs.in","r",stdin);
freopen("lcs.out","w",stdout);
scanf("%s%s",s1+,s2+);
l1=strlen(s1+); l2=strlen(s2+);
for(int i=;i<=l1;i++)
for(int j=;j<=l2;j++)
if(s1[i]==s2[j]) dp[i][j]=dp[i-][j-]+;
else dp[i][j]=max(dp[i-][j],dp[i][j-]);
printf("%d",dp[l1][l2]);
}

题面修改:后面的DEF分别改为CBA

首先很关键的一点:

因为要求操作字典序最小,所以DEF没有用

例如:下面转90相当于上面转270

然后 大模拟

考场上复制时漏改一个数组,丢了60分o(╥﹏╥)o

#include<cstdio>
#include<algorithm>
using namespace std;
int n,tmp[];
int ans[];
int L[][],R[][],U[][],D[][],F[][],B[][];
bool ok;
bool judge(int sum)
{
if(!(L[][]==L[][] && L[][]==L[][] && L[][]==L[][])) return false;
if(!(R[][]==R[][] && R[][]==R[][] && R[][]==R[][])) return false;
if(!(U[][]==U[][] && U[][]==U[][] && U[][]==U[][])) return false;
if(!(D[][]==D[][] && D[][]==D[][] && D[][]==D[][])) return false;
if(!(F[][]==F[][] && F[][]==F[][] && F[][]==F[][])) return false;
if(!(B[][]==B[][] && B[][]==B[][] && B[][]==B[][])) return false;
for(int i=;i<=sum;i++) ans[i]=tmp[i];
ans[]=sum;
return true;
}
void self90(int k[][],int a1,int a2,int b1,int b2,int c1,int c2,int d1,int d2)
{
int t=k[a1][a2];
k[a1][a2]=k[b1][b2]; k[b1][b2]=k[c1][c2]; k[c1][c2]=k[d1][d2]; k[d1][d2]=t;
}
void other90(int k1[][],int a1,int a2,int k2[][],int b1,int b2,int k3[][],int c1,int c2,int k4[][],int d1,int d2)
{
int t=k1[a1][a2];
k1[a1][a2]=k2[b1][b2]; k2[b1][b2]=k3[c1][c2]; k3[c1][c2]=k4[d1][d2]; k4[d1][d2]=t;
a2^=; b2^=; c2^=; d2^=;
t=k1[a1][a2];
k1[a1][a2]=k2[b1][b2]; k2[b1][b2]=k3[c1][c2]; k3[c1][c2]=k4[d1][d2]; k4[d1][d2]=t;
}
void other90_(int k1[][],int a1,int a2,int k2[][],int b1,int b2,int k3[][],int c1,int c2,int k4[][],int d1,int d2)
{
int t=k1[a1][a2];
k1[a1][a2]=k2[b1][b2]; k2[b1][b2]=k3[c1][c2]; k3[c1][c2]=k4[d1][d2]; k4[d1][d2]=t;
a1^=; b1^=; c1^=; d1^=;
t=k1[a1][a2];
k1[a1][a2]=k2[b1][b2]; k2[b1][b2]=k3[c1][c2]; k3[c1][c2]=k4[d1][d2]; k4[d1][d2]=t;
}
void other90_3(int k1[][],int a1,int a2,int k2[][],int b1,int b2,int k3[][],int c1,int c2,int k4[][],int d1,int d2)
{
int t=k1[a1][a2];
k1[a1][a2]=k2[b1][b2]; k2[b1][b2]=k3[c1][c2]; k3[c1][c2]=k4[d1][d2]; k4[d1][d2]=t;
}
void self180(int k[][],int a1,int a2,int b1,int b2,int c1,int c2,int d1,int d2)
{
swap(k[a1][a2],k[b1][b2]);
swap(k[c1][c2],k[d1][d2]);
}
void other180(int k1[][],int a1,int a2,int k2[][],int b1,int b2,int k3[][],int c1,int c2,int k4[][],int d1,int d2)
{
swap(k1[a1][a2],k2[b1][b2]);
swap(k3[c1][c2],k4[d1][d2]);
a2^=; b2^=; c2^=; d2^=;
swap(k1[a1][a2],k2[b1][b2]);
swap(k3[c1][c2],k4[d1][d2]);
}
void other180_(int k1[][],int a1,int a2,int k2[][],int b1,int b2,int k3[][],int c1,int c2,int k4[][],int d1,int d2)
{
swap(k1[a1][a2],k2[b1][b2]);
swap(k3[c1][c2],k4[d1][d2]);
a1^=; b1^=; c1^=; d1^=;
swap(k1[a1][a2],k2[b1][b2]);
swap(k3[c1][c2],k4[d1][d2]);
}
void other180_3(int k1[][],int a1,int a2,int k2[][],int b1,int b2,int k3[][],int c1,int c2,int k4[][],int d1,int d2)
{
swap(k1[a1][a2],k2[b1][b2]);
swap(k3[c1][c2],k4[d1][d2]);
}
void dfs(int x,char ty)
{
if(ok) return;
if(judge(x-)) { ok=true; return; }
if(x==n+) return;
if(ty!='A')
{
self90(U,,,,,,,,);
other90(F,,,R,,,B,,,L,,);
tmp[x]=; dfs(x+,'A');
if(ok) return;
self90(U,,,,,,,,);
other90(F,,,L,,,B,,,R,,); self180(U,,,,,,,,);
other180(F,,,B,,,R,,,L,,);
tmp[x]=; dfs(x+,'A');
if(ok) return;
self180(U,,,,,,,,);
other180(F,,,B,,,R,,,L,,); self90(U,,,,,,,,);
other90(F,,,L,,,B,,,R,,);
tmp[x]=; dfs(x+,'A');
self90(U,,,,,,,,);
other90(F,,,R,,,B,,,L,,);
if(ok) return; }
if(ty!='B')
{
self90(L,,,,,,,,);
other90_(F,,,U,,,B,,,D,,);
tmp[x]=; dfs(x+,'B');
if(ok) return;
self90(L,,,,,,,,);
other90_(F,,,D,,,B,,,U,,); self180(L,,,,,,,,);
other180_(F,,,B,,,U,,,D,,);
tmp[x]=; dfs(x+,'B');
if(ok) return;
self180(L,,,,,,,,);
other180_(F,,,B,,,U,,,D,,); self90(L,,,,,,,,);
other90_(F,,,D,,,B,,,U,,);
tmp[x]=; dfs(x+,'B');
if(ok) return;
self90(L,,,,,,,,);
other90_(F,,,U,,,B,,,D,,);
}
if(ty!='C')
{
self90(F,,,,,,,,);
other90_3(R,,,U,,,L,,,D,,);
other90_3(R,,,U,,,L,,,D,,);
tmp[x]=; dfs(x+,'C');
if(ok) return;
self90(F,,,,,,,,);
other90_3(R,,,D,,,L,,,U,,);
other90_3(R,,,D,,,L,,,U,,); self180(F,,,,,,,,);
other180_3(R,,,L,,,U,,,D,,);
other180_3(R,,,L,,,U,,,D,,);
tmp[x]=; dfs(x+,'C');
if(ok) return;
self180(F,,,,,,,,);
other180_3(R,,,L,,,U,,,D,,);
other180_3(R,,,L,,,U,,,D,,); self90(F,,,,,,,,);
other90_3(R,,,D,,,L,,,U,,);
other90_3(R,,,D,,,L,,,U,,);
tmp[x]=; dfs(x+,'C');
if(ok) return;
self90(F,,,,,,,,);
other90_3(R,,,U,,,L,,,D,,);
other90_3(R,,,U,,,L,,,D,,);
}
}
int main()
{
freopen("cube.in","r",stdin);
freopen("cube.out","w",stdout);
scanf("%d",&n);
scanf("%d%d%d%d",&U[][],&U[][],&U[][],&U[][]);
scanf("%d%d%d%d",&F[][],&F[][],&F[][],&F[][]);
scanf("%d%d%d%d",&L[][],&L[][],&L[][],&L[][]);
scanf("%d%d%d%d",&R[][],&R[][],&R[][],&R[][]);
scanf("%d%d%d%d",&D[][],&D[][],&D[][],&D[][]);
scanf("%d%d%d%d",&B[][],&B[][],&B[][],&B[][]);
dfs(,'G');
for(int i=;i<=ans[];i++) printf("%d ",ans[i]);
return ;
}

2017北京国庆刷题Day5 afternoon的更多相关文章

  1. 2017北京国庆刷题Day1 afternoon

    期望得分:100+100+100=300 实际得分:100+100+100=300 T1 一道图论好题(graph) Time Limit:1000ms   Memory Limit:128MB 题目 ...

  2. 2017北京国庆刷题Day2 afternoon

    期望得分:100+100+50=250 实际得分:100+70+50=220 T1 最大值(max) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK有一 ...

  3. 2017北京国庆刷题Day5 morning

    期望得分:0+60+60=120 实际得分:0+30+60=90 令g=gcd(X11,X12,X13……) 则行列式可能为D的充要条件为g|D 1.g|D为必要条件: 由定义来算行列式的时候,每一项 ...

  4. 2017北京国庆刷题Day4 afternoon

    期望得分:100+100+0=200 实际得分:5+0+0=5 每加入一个数,x的因数位置++ 注意:根号x枚举时,如果x是完全平方数,根号x会重复累计2次,要减去 考场上没减,5分 /(ㄒoㄒ)/~ ...

  5. 2017北京国庆刷题Day6 afternoon

    期望得分:100+100+40=240 实际得分:100+0+40=140 二进制拆分.二进制前缀和 #include<cstdio> #include<iostream> u ...

  6. 2017北京国庆刷题Day3 afternoon

    期望得分:100+0+30=130 实际得分:100+36.5+0=136.5 T3 一个变量写混了,丢了30.. 模拟栈 #include<cstdio> #include<cst ...

  7. 2017北京国庆刷题Day7 afternoon

    期望得分:100+30+100=230 实际得分:60+30+100=190 排序去重 固定右端点,左端点单调不减 考场上用了二分,没去重,60 #include<cstdio> #inc ...

  8. 2017北京国庆刷题Day7 morning

    期望得分:100+0+100=200 实际得分:100+20+0=120 离散化搞搞 #include<cstdio> #include<iostream> #include& ...

  9. 2017北京国庆刷题Day3 morning

    期望得分:100+60+0=160 实际得分:100+30+0=130 考场上用的哈希 #include<cstdio> #include<cstring> #include& ...

随机推荐

  1. Java 将数字转为16进制,然后转为字符串类型 将空格去掉。终结版

    //十进制转为十六进制 public class ArrayTest7 { public static void main(String[] args){ System.out.println(toH ...

  2. BETA阶段冲刺集合

    冲刺开始: https://www.cnblogs.com/LZTZ/p/9097296.html 第一天: https://www.cnblogs.com/LZTZ/p/9097303.html 第 ...

  3. 转 下一代云计算模式:Docker正掀起个性化商业革命

    下一代云计算模式:Docker正掀起个性化商业革命 作者: 吴宁川  来源: ITValue  发布时间: 2015-09-20 10:41  阅读: 14052 次  推荐: 26   原文链接   ...

  4. HTML图片标签

    <body> <!-- 使用img标签来向网页中引入外部的图片, img标签也是一个自结束标签 属性: src:设置一个外部图片的路径 alt:可以用来设置图片不能显示时,就会显示图 ...

  5. 3dContactPointAnnotationTool开发日志(二九)

      今天想着在Windows平台上跑通那个代码,不过它的官网上写的支持平台不包括windows,但我还是想试试,因为看他的依赖好像和平台的关系不是特别大.   看了下它的py代码,不知道是py2还是p ...

  6. php 多维数组排序

    PHP中array_multisort可以用来一次对多个数组进行排序,或者根据某一维或多维对多维数组进行排序. 关联(string)键名保持不变,但数字键名会被重新索引. 输入数组被当成一个表的列并以 ...

  7. Java MD5加密类

    /************************************************* md5 类实现了RSA Data Security, Inc.在提交给IETF 的RFC1321中 ...

  8. C语言添加宏开关

    原文地址:http://blog.csdn.net/cp1300/article/details/7773239 我们在写程序的时候,总是或多或少会加入一些printf之类的语句用于输出调试信息,但是 ...

  9. Java多线程 -yield用法

    前几天复习了一下多线程,发现有许多网上讲的都很抽象,所以,自己把网上的一些案例总结了一下! 一. Thread.yield( )方法: 使当前线程从执行状态(运行状态)变为可执行态(就绪状态).cpu ...

  10. idea导出包含main函数的jar

    1.首先打开File->project stucture->Artifacts 2.按照下图方式: 3.选择面main函数的所在的类,选择MAINFEST.MF问的生成路径 这里一定选择 ...