暑假集训系列题解(四)
题目1
题目链接
题目描述
We have N cards numbered 1 to N. Each side of each card has a color represented by a positive integer.
One side of Card i has a color ai, and the other side has a color bi.
For each card, you can choose which side shows up. Find the maximum possible number of different colors showing up.
Constraints
1≤N≤200000
1≤ai,bi≤400000
All numbers in input are integers.
输入
Input is given from Standard Input in the following format:
N
a1 b1
a2 b2
:
aN bN
输出
Print the answer.
样例输入
【样例1】
4
1 2
1 3
4 2
2 3
【样例2】
2
111 111
111 111
【样例3】
12
5 2
5 6
1 2
9 7
2 7
5 5
4 2
6 7
2 2
7 8
9 7
1 8
样例输出
【样例1】
4
【样例2】
1
【样例3】
8
提示
样例1解释
We can choose the sides with 1, 3, 4, 2 to have four colors.
样例2解释
They are painted with just one color.
题解
并查集,建立连通块。分两种情况:
- 连通块无环,为一棵树,则该连通块对答案的贡献度为点的个数减1,例如1-2,2-3,3-4,这种情况答案为3
- 连通块有环,则该连通块对答案的贡献度为点的数目,例如1-2,2-3,3-1,该情况答案为4
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll fa[400500]={0};
ll huan[400500]={0};
ll sum[400500]={0};
ll findfa(ll n)
{
if(n==fa[n])
return n;
return fa[n]=findfa(fa[n]);
}
int main()
{
ll n,s,e;
for(ll i=1;i<=400000;i++)
fa[i]=i;
scanf("%lld",&n);
for(ll i=1;i<=n;i++)
{
ll x,y;
scanf("%lld%lld",&x,&y);
ll fx=findfa(x);
ll fy=findfa(y);
if(fx==fy)
huan[fx]=huan[fy]=1;
else
fa[fy]=fx;
}
for(ll i=1;i<=400000;i++)
{
findfa(i);
huan[fa[i]]|=huan[i];
sum[fa[i]]++;
}
ll ans=0;
for(ll i=1;i<=400000;i++)
{
if(sum[i]!=0)
{
if(huan[i])
ans+=sum[i];
else
ans+=sum[i]-1;
}
}
cout<<ans<<endl;
}
题目2
题目链接
题目描述
Given a N×M binary matrix. Please output the size of second large rectangle containing all "1".
Containing all "1" means that the entries of the rectangle are all "1".
A rectangle can be defined as four integers x1,y1,x2,y2 where 1≤x1≤x2≤N and 1≤y1≤y2≤M. Then, the rectangle is composed of all the cell (x, y) where x1≤x≤x2 and y1≤y≤y2. If all of the cell in the rectangle is "1", this is a valid rectangle.
Please find out the size of the second largest rectangle, two rectangles are different if exists a cell belonged to one of them but not belonged to the other.
输入
The first line of input contains two space-separated integers N and M.
Following N lines each contains M characters cij.
1≤N,M≤1000
N×M≥2
cij∈"01"
输出
Output one line containing an integer representing the answer. If there are less than 2 rectangles containning all "1", output "0".
样例输入
1 2
01
样例输出
0
题解
构造列方向的前缀和,后用单调栈求出区间最小值和区间长度乘积的第二大值即可。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int sum[2050][2050] = {0};
int a[2050][2050] = {0};
struct node
{
ll pos, val;
};
node s[100500] = {0};
int main()
{
int n, m;
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
scanf("%1d", &a[i][j]);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{
if (a[i][j])
sum[i][j] = sum[i - 1][j] + a[i][j];
else
sum[i][j] = 0;
}
ll ans = 0;
ll max1 = 0, max2 = 0;
for (ll i = 1; i <= n; i++)
{
ll top = 0;
for (ll j = 1; j <= m + 1; j++)
{
if (top == 0)
{
s[++top] = {j, sum[i][j]};
}
else
{
while (s[top].val > sum[i][j])
{
ll tmp = (ll)(j - s[top - 1].pos - 1) * (ll)s[top].val;
ll tmp1 = (ll)(j - s[top - 1].pos - 2) * (ll)s[top].val;
ll tmp2 = (ll)(j - s[top - 1].pos - 1) * (ll)(s[top].val - 1);
top--;
if (tmp > max1)
swap(max1, tmp);
if (tmp > max2)
swap(max2, tmp);
if (tmp1 > max1)
swap(max1, tmp1);
if (tmp1 > max2)
swap(max2, tmp1);
if (tmp2 > max1)
swap(max1, tmp2);
if (tmp2 > max2)
swap(max2, tmp2);
}
s[++top] = {j, sum[i][j]};
}
}
}
cout << max2 << endl;
}
题目3
题目链接
题目描述
Given positive integers N and M, find the remainder when $⌊10^N/M⌋$ is divided by M.
What is ⌊x⌋?⌊x⌋ denotes the greatest integer not exceeding x. For example:
⌊2.5⌋=2
⌊3⌋=3
⌊9.9999999⌋=9
⌊100/3⌋=⌊33.33...⌋=33
Constraints
1≤N≤$10^{18}$
1≤M≤10000
输入
Input is given from Standard Input in the following format: N a1 b1 a2 b2 : aN bN
输出
Print the answer.
样例输入
【样例1】
1 2
【样例2】
2 7
【样例3】
1000000000000000000 9997
样例输出
【样例1】
1
【样例2】
0
【样例3】
9015
提示
样例1解释:
We have ⌊10^1/2⌋=5, so we should print the remainder when 5 is divided by 2, that is, 1.
题解
$⌊\frac{10^N}{M}⌋ \% m = ⌊\frac{10^N}{M}-k*m⌋ \% m =⌊\frac{10^N-k*m^2}{M}⌋\% m=⌊\frac{10^N \% m^2}{M}⌋\% m$
$⌊\frac{10^N}{M}⌋ \% m = ⌊\frac{10^N}{M}-k*m⌋ \% m =⌊\frac{10^N-k*m^2}{M}⌋\% m=⌊\frac{10^N \% m^2}{M}⌋\% m$
所以,只需要利用快速幂算法计算出 $ 10 ^N \% m^2$ 即可
如果Latex无法显示,请看下面图片:
代码
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3, "Ofast", "inline")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
map<ll, ll> mp;
vector<ll> v;
int main()
{
ll n, m;
cin >> n >> m;
ll mod = m * m, ans1 = 1, ans2 = 10;
while (n != 0)
{
if (n % 2)
ans1 = (ans1 * ans2) % mod;
ans2 = (ans2 * ans2) % mod;
n /= 2;
}
ll ans = (ans1 / m + m) % m;
cout << ans << endl;
}