B - Ralph And His Magic Field
题意:
有一个
n
×
m
n\times m
n×m的矩阵和
k
k
k,在每个格上填数使每一行每一列的和都等于
k
k
k,
k
k
k为
0
0
0或
1
1
1,问有多少种选法
思路:(思维)
由于
k
k
k只能是
1
1
1或
−
1
-1
−1,所以每个格子只能填
1
1
1或
−
1
-1
−1,如果当前行只剩下最后一个,那么成绩不是
1
1
1就是
−
1
-1
−1,所以在
k
k
k确定的情况下,最后一个格子也就确定了,
列和一样,所以,对于
n
n
n行
m
m
m列的矩阵先把左上角
n
−
1
n-1
n−1行
m
−
1
m-1
m−1列都填完,方案数为
2
(
n
−
1
)
(
m
−
1
)
2^{(n-1)(m-1)}
2(n−1)(m−1),那么最后一行和最后一列也就确定了。
!!!
如果
n
,
m
n,m
n,m为一奇一偶是且
k
=
−
1
k=-1
k=−1是无解,假设
n
n
n是奇数,
m
m
m是偶数,
则在每一行上必然要放奇数个
−
1
-1
−1,那么这样可以知道
−
1
-1
−1的总个数是奇数(奇数行,每行奇数个
−
1
)
-1)
−1)
但是,同时每一列上也要放奇数个-1,那么-1的总个数是偶数(偶数列,每列奇数个
−
1
-1
−1),互相矛盾,所以不存在这样的方案。
AC代码:
#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define SZ(x) ((int)(x).size())
#define ALL(x) (x).begin(),(x).end()
#define int long long
typedef long long ll;
typedef pair<int,int> PII;
const int N=1e5+10;
const int mod=1e9+7;
int n,m,k;
int qmi(int a,int b)
{
int res=1;
while(b)
{
if(b&1) res=res*a%mod;
b>>=1;
a=a*a%mod;
}
return res%mod;
}
signed main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin>>n>>m>>k;
if((n+m)&1&&k==-1) cout<<0;
else
{
int ans=1;
ans=qmi(2,n-1);
ans=qmi(ans,m-1);
cout<<ans;
}
return 0;
}
C - Code For 1
题意:
将
n
n
n分解为
n
2
,
n
%
2
,
n
2
\frac{n}{2}, n\%2, \frac{n}{2}
2n,n%2,2n三部分,再将
n
2
\frac {n}{2}
2n分解,得到一个序列只有
0
0
0和
1
1
1,问
l
∼
r
l\sim r
l∼r有几个
1
1
1
题解:分治
分析得出一个数全分解完的长度为
l
e
n
=
2
x
−
1
len=2^x-1
len=2x−1,因为最小的
2
2
2分解变成
1
,
0
,
1
1,0,1
1,0,1,长度为
3
3
3,所以
4
,
5
4,5
4,5分解的长度为
2
∗
3
+
1
=
7
2*3+1=7
2∗3+1=7,以此类推,初始左右端点为
1
,
l
e
n
1,len
1,len,然后分成左中右递归得出答案
AC代码:
#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define SZ(x) ((int)(x).size())
#define ALL(x) (x).begin(),(x).end()
#define int long long
typedef long long ll;
typedef pair<int,int> PII;
const int N=10;
const int mod=1e9+7;
int n,L,R;
int dfs(int n,int l,int r)
{
if(l>R||r<L) return 0;
if(n<=1)
{
if(l>=L&&r<=R) return n;
else return 0;
}
int mid=l+r>>1;
return dfs(n/2,l,mid-1)+dfs(n%2,mid,mid)+dfs(n/2,mid+1,r);
}
signed main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin>>n>>L>>R;
int len=1;
while(len<n) len=2*len+1;
//cout<<len<<endl;
cout<<dfs(n,1,len);
return 0;
}
J - Remove Extra One
题意:
给一个长度为
n
n
n的排列
p
p
p,找一个元素,使得从排列中删掉这个元素以后排列的
r
e
c
o
r
d
s
records
records最多,一个
r
e
c
o
r
d
record
record是一个元素
a
i
a_i
ai是
1...
i
1...i
1...i的
m
a
x
max
max
思路:
d
p
x
dp_x
dpx表示删掉
x
x
x后对整体
r
e
c
o
r
d
s
records
records的影响,维和区间最大值,次大值
m
a
x
1
,
m
a
x
2
max1,max2
max1,max2,如果
x
x
x是最大值,删去
x
x
x会使
r
e
c
o
r
d
−
1
record-1
record−1,
d
p
x
=
d
p
x
−
1
dp_x=dp_x-1
dpx=dpx−1,如果
x
x
x为次大值,那么删去最大值会使
r
e
c
o
r
d
+
1
record+1
record+1,
d
p
m
a
x
1
=
d
p
m
a
x
1
+
1
dp_{max1}=dp_{max1}+1
dpmax1=dpmax1+1
AC代码:
#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define mst(a,x) memset(a,x,sizeof(a));
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define SZ(x) ((int)(x).size())
#define ALL(x) (x).begin(),(x).end()
#define int long long
typedef long long ll;
typedef pair<int,int> PII;
const int N=1e5+10;
const int mod=1e9+7;
int n,x;
int max1,max2;
int dp[N];
void solve()
{
cin>>n;
rep(i,1,n)
{
cin>>x;
if(x>max1)
{
max2=max1;
max1=x;
dp[x]--;
}
else if(x>max2)
{
max2=x;
dp[max1]++;
}
}
int ans=1;
rep(i,1,n) if(dp[i]>dp[ans]) ans=i;
cout<<ans;
}
signed main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
//int t;cin>>t;while(t--)
solve();
return 0;
}