Solution
A
由于无论 与谁做或运算,结果均不会小于 ;所以,我们只需要输出 ,保证以 结尾与 开头的区间一定满足要求。
B
显然,最终所有的东西都会集中到底部或右侧;此时,我们只需要让最右边一列的字符全为 ,底侧的字符全为 ,即可满足要求。
故答案为右侧 的数量与底侧 的数量之和。
C
显然,最大的数是不会往外连边的,其他的数一定会往外连至少一条边,故至少有 条边。
反面考虑。由于有 个顶点,我们要让它不成环,边的数量不能超过 ,即必须让该图成为一个树的形态才可以。故只能有 条边。
尝试构造一些满足"所有值非 的节点向外连边的数量均为 条"的排列,可以发现,这些排列都是单峰序列。峰左的数向它右边的数连边,峰右的数向它左边的数连边。
于是,现在我们思考如何求出单峰序列的数量。显然,峰值一定为 。可以发现,只要选定了峰左哪些数出现了,那么整个序列都确定下来了。当 被选做峰顶的时候,显然剩下有 个数可选;设峰顶的位置为 ,则峰左的数有 种选择。
故答案为 。
这个式子可以进一步优化:
于是,我们只需要使用普通幂与阶乘,并注意减法的取模方式即可通过本题。
时间复杂度 。
D
首先,可以发现,对于一个 的子矩阵,它是由四个 的子矩阵组合而成的;而这四个 的子矩阵各数之和必须都是奇数,故一个 的子矩阵的各数之和只能是奇数的四倍,即偶数,不符题意。所以,可以推出,如果 的矩形中含有任何一个 的子矩阵,均应输出 。注意,当一个长方形含有 的子矩阵时,当且仅当 。
此时,我们的长方形的长度为 ,宽度为 ,必有 或 。不妨设 ,即 ,显然这时长方形是一条宽度为 或 或 的链。
于是,我们考虑状压 。由于每一行的状态并不多(最多 个),可以考虑用一个压位十进制数表示每一位的状态,并暴力转移即可。注意,此时我们只需要保证任何 的子矩阵中和为奇数,其他并无限制。
总时间复杂度为 ,其中 是一个巨大的常数,但是并不妨碍我们 本题。
E
比赛场上脑子瓦特, 没做出来QAQ
本题做法十分简单。首先,我们从 号节点对整个图进行深搜,得到了每个节点的深度。对于第一个问题而言,如果有节点的深度达到了 ,则直接递归打印该路径。
如果没达到呢?我们不得不开始思考问题 。并不显然地发现,对于同深度的节点两两配对即可。
为什么呢?首先,由于它们是同深度的,它们之间不会有边。同时,对于 与 (不妨设 的深度小于 的深度)不可能出现 形成一个独立的连通图的情况。因为若形成连通图,不可能满足 与 属于同一深度且 与 属于同一深度,因为搜到 的时候, 直接把另外三个点给全部搜了一遍。
所以,这种做法是正确的。
比赛的时候想到了不会证明不敢写QAQ
Code
A
#include <bits/stdc++.h>
#define int long long
using namespace std;
int t,n;
int a[200005];
signed main()
{
cin>>t;
while (t--)
{
cin>>n;
for (int i=1;i<=n;i++) cout<<i<<' ';
cout<<endl;
}
return 0;
}
B
#include <bits/stdc++.h>
#define int long long
using namespace std;
int t,n,m;
char a[105][105];
signed main()
{
cin>>t;
while (t--)
{
cin>>n>>m;
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++) cin>>a[i][j];
}
int ans=0;
for (int i=1;i<=n-1;i++)
{
if (a[i][m]!='D') ans++;
}
for (int i=1;i<=m-1;i++)
{
if (a[n][i]!='R') ans++;
}
cout<<ans<<endl;
}
return 0;
}
C
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int mod=1e9+7;
int n;
int quick_power(int a,int b)
{
int res=1;
for (;b;b=b>>1,a=(a*a)%mod)
{
if (b&1) res=(res*a)%mod;
}
return res;
}
signed main()
{
cin>>n;
int tot=1;
for (int i=1;i<=n;i++) tot=(tot*i)%mod;
tot=((tot-quick_power(2,n-1))%mod+mod)%mod;
cout<<tot<<endl;
return 0;
}
D
#include <bits/stdc++.h>
#define int long long
#define inf 2000000007
using namespace std;
int n,m,x,ans=inf;
int dp[1000005][8];
char ch;
vector<int> a[1000005];
vector<int> b[1000005];
signed main()
{
cin>>n>>m;
if (n>=4&&m>=4) return cout<<-1<<endl,0;
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++) cin>>ch,a[i].push_back(ch-'0');
}
if (n<m)//2 4
{
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++) b[j].push_back(a[i][j-1]);
}
for (int i=1;i<=n;i++) a[i].clear();
swap(n,m);
for (int i=1;i<=n;i++)
{
for (int j=0;j<m;j++) a[i].push_back(b[i][j]);
}
}
for (int i=1;i<=n;i++)
{
for (int j=0;j<8;j++) dp[i][j]=inf;
}
if (m==1) return cout<<0<<endl,0;
else if (m==2)
{
for (int i=0;i<4;i++)
{
int x=i>>1,y=i&1;
dp[1][i]=(a[1][0]!=x)+(a[1][1]!=y);
}
for (int i=2;i<=n;i++)
{
for (int j=0;j<4;j++)
{
int x=j>>1,y=j&1;
for (int k=0;k<4;k++)
{
int X=k>>1,Y=k&1;
if ((x+y+X+Y)%2) dp[i][j]=min(dp[i][j],dp[i-1][k]);
}
dp[i][j]+=(a[i][0]!=x)+(a[i][1]!=y);
}
}
for (int i=0;i<4;i++) ans=min(ans,dp[n][i]);
}
else if (m==3)
{
for (int i=0;i<8;i++)
{
int x=i>>2,y=(i>>1)&1,z=i&1;
dp[1][i]=(x!=a[1][0])+(y!=a[1][1])+(z!=a[1][2]);
}
for (int i=2;i<=n;i++)
{
for (int j=0;j<8;j++)
{
int x=j>>2,y=(j>>1)&1,z=j&1;
for (int k=0;k<8;k++)
{
int X=k>>2,Y=(k>>1)&1,Z=k&1;
if ((x+y+X+Y)%2&&(y+z+Y+Z)%2) dp[i][j]=min(dp[i][j],dp[i-1][k]);
}
dp[i][j]+=(a[i][0]!=x)+(a[i][1]!=y)+(a[i][2]!=z);
}
}
for (int i=0;i<8;i++) ans=min(ans,dp[n][i]);
}
cout<<ans<<endl;
return 0;
}
E
#include <bits/stdc++.h>
#define int long long
using namespace std;
int t,n,m,u,v,maxv=0,ans=0,cnt=0,pos;
int head[500005],visited[500005],depth[500005];
vector<int> a[500005];
struct edge
{
int next;
int to;
}e[2000005];
inline void add_edge(int u,int v)
{
cnt++;
e[cnt].to=v;
e[cnt].next=head[u];
head[u]=cnt;
}
inline int read()
{
int s=0,w=1;
char ch=getchar();
while (ch<'0'||ch>'9')
{
if (ch=='-') w=-w;
ch=getchar();
}
while (ch>='0'&&ch<='9')
{
s=(s<<1)+(s<<3)+(ch^'0');
ch=getchar();
}
return s*w;
}
inline void dfs(int now,int dep)
{
a[dep].push_back(now);
depth[now]=dep;
visited[now]=1;
if (depth[now]>maxv)
{
maxv=depth[now];
pos=now;
}
for (int i=head[now];i;i=e[i].next)
{
if (!visited[e[i].to]) dfs(e[i].to,dep+1);
}
}
inline void work(int now)
{
if (depth[now]==1)
{
cout<<now<<' ';
return;
}
for (int i=head[now];i;i=e[i].next)
{
if (depth[e[i].to]+1==depth[now])
{
work(e[i].to);
break;
}
}
cout<<now<<' ';
}
signed main()
{
cin>>t;
while (t--)
{
cin>>n>>m;
maxv=0,cnt=0;
for (int i=1;i<=n;i++)
{
head[i]=visited[i]=0;
a[i].clear();
}
for (int i=1;i<=2*m;i++) e[i].next=e[i].to=0;
for (int i=1;i<=m;i++)
{
u=read(),v=read();
add_edge(u,v);
add_edge(v,u);
}
dfs(1,1);
if (maxv>=(n+1)/2)
{
cout<<"PATH"<<endl;
cout<<maxv<<endl;
work(pos);
cout<<endl;
continue;
}
else
{
ans=0;
for (int i=1;i<=n;i++) ans+=a[i].size()/2;
cout<<"PAIRING"<<endl;
cout<<ans<<endl;
for (int i=1;i<=n;i++)
{
if (a[i].size()<=1) continue;
for (int j=0;j<a[i].size()-1;j+=2) cout<<a[i][j]<<' '<<a[i][j+1]<<endl;
}
}
}
return 0;
}