1300-1600
Set Construction
令第i个集合有一个专属元素i,如果i集合为j的子集,将i集合的专属元素加入到j中
Jatayu’s Balanced Bracket Sequence
找规律,每次遇到()答案减一
Garage
多写几组 b 2 − a 2 b^2-a^2 b2−a2如: b − a = 1 b-a=1 b−a=1, b − a = 2 b-a=2 b−a=2,然后发现规律只有凡是4的倍数都不会存在,还有一个特例是6,O(1)直接计算 n + 3 + ( n / 3 ) n+3+(n/3) n+3+(n/3) ,其中 n < = 3 n<=3 n<=3特判即可
Even-Odd XOR
要满足题目条件,即 a 1 a_1 a1 ⨁ \bigoplus ⨁ a 2 a_2 a2 ⨁ \bigoplus ⨁ . . . . . ..... ..... ⨁ \bigoplus ⨁ a n = 0 a_n=0 an=0,之后留下三个位置,填上两个足够大的数(放止重复),最后一个数只需为前n-1个数的异或和即可
Counting Rectangles
考虑到二维的条件,转化为二维的前缀和
Min-Max Array Transformation
若
a
i
<
=
b
j
a_i<=b_j
ai<=bj(
1
<
=
i
<
=
n
1<=i<=n
1<=i<=n),满足
i
i
i 都存在这种
j
j
j 唯一对应,即满足
对于每个
a
i
a_i
ai 的最小解,即其与
b
i
b_i
bi 的差值
对于每个
a
i
a_i
ai 的最大解,考虑从多个不同情况求,对于
a
n
−
1
a_{n-1}
an−1,要让他匹配
b
n
b_n
bn,那么必须满足
a
n
<
=
b
n
−
1
a_n<=b_{n-1}
an<=bn−1,之后找规律:
类似的如果
a
n
−
1
a_{n-1}
an−1 这种情况不满足,那么
a
n
−
2
a_{n-2}
an−2 匹配
b
n
b_n
bn 也一定不行
对于任意的
a
i
a_i
ai ,都可以从
a
i
+
1
a_{i+1}
ai+1 最大匹配的
b
i
b_i
bi 开始向前匹配
用双指针实现线性复杂度
void solve()
{
int n;
cin>>n;
vector<int> a(n+1),b(n+1);
for (int i=1;i<=n;i++)
cin>>a[i];
for (int i=1;i<=n;i++)
cin>>b[i];
for (int l=1,r=1;l<=n;l++)
{
while (a[l]>b[r]){r++;}
cout<<b[r]-a[l]<<" ";
}
cout<<"\n";
vector<int> ans(n+1);
for (int l=n,r=n;l>=1;l--)
{
if (b[l]<a[l+1]&&l!=n)
r=l;
ans[l]=b[r]-a[l];
}
for (int i=1;i<=n;i++)
cout<<ans[i]<<" ";
cout<<"\n";
}
Fighting Tournament
模拟找到规律,当实力最强的那个人到第一之后,其他人胜利场次不会改变
Madoka and Formal Statement
易得 a i > b i a_i>b_i ai>bi 或 b i > = b i + 1 + 2 b_i>=b_{i+1}+2 bi>=bi+1+2 则不满足
Color with Occurrences
先求出每个子串对应的位置,转化为多个区间覆盖问题
Party
对于m为偶数,答案显然为0
对于m为奇数,只需除去某一个奇点;另外考虑除去偶点是否有满足的情况:即除去某两个有公共边的偶点(两个奇点在之前包括)
Color the Picture
考虑行n或列m。将行分成几份,每份行数不小于二,若能将每份涂上一种颜色即可。
某种颜色总数
[
a
i
/
m
]
>
=
2
[a_i/m]>=2
[ai/m]>=2,统计一下这类颜色总数和,判断是否大于n。
特例:当所有合法颜色所涂的行数=m-1,如果不存在
[
a
i
/
m
>
2
]
[a_i/m>2]
[ai/m>2],则也不满足
int a[100005],k;
bool pan(int n,int m)
{
if (m==3)
{
for (int i=1;i<=k;i++)
{
if (a[i]/n>=3)
return 1;
}
return 0;
}
else
{
ll sum=0;
bool flag=0;
for (int i=1;i<=k;i++)
{
if (a[i]/n>=2)
{
sum+=a[i]/n;
if (a[i]/n>2)
flag=1;
}
}
if (sum>=m)
{
if (!flag&&(sum-m)%2==1)
return 0;
return 1;
}
return 0;
}
}
void solve()
{
int n,m;
cin>>n>>m>>k;
for (int i=1;i<=k;i++)
cin>>a[i];
if (pan(n,m)||pan(m,n))
cout<<"Yes\n";
else
cout<<"No\n";
}
3SUM Closure
n足够小的时候暴力枚举;直接研究有序的数组:只有当-x 0 0…0 0 x 或出现至少n-1个0的情况才可行,其余情况定会出现三个非负数或三个非正数相加
Doremy’s IQ
如果我们在某个位置血量-1,那么可以贪心不测试,直到最后一个测试使血量变为0
按照这个思路我们要尽可能晚选大的,必要下也就是让血量一直为正数(基于血量最终会变为0)
从后往前枚举,假设最后血量为0,如果遇到
h
<
a
i
,
h
+
+
h<a_i,h++
h<ai,h++,最后到血量为q+1结束即可
Number Reduction
首先确定开头最小的那个数字,记录那个数字到首位需要多少次操作。
剩下的操作次数用于筛去不要的的数,当要存储某个数时,比较其前面已有的数,存到合适的位置,其余的数筛掉 2 插入1 3 5 k=2 转变为1 2
Almost All Multiples
对于首位无需考虑,构造
a
i
=
i
a_i=i
ai=i(
2
<
i
=
<
=
n
−
1
2<i=<=n-1
2<i=<=n−1),
a
x
a_x
ax=n,然后只需不断将
a
x
a_x
ax与后面
a
i
a_i
ai
(
a
i
a_i
ai%
x
=
=
0
x= =0
x==0)交换位置即可
void solve()
{
int n,x;
cin>>n>>x;
vector<int> a(n+1);
a[1]=x;
a[n]=1;
for (int i=2;i<=n-1;i++)
{
if (i==x)
a[i]=n;
else
a[i]=i;
}
if (x==n)
{
for (int i=1;i<=n;i++)
cout<<a[i]<<" ";
cout<<"\n";
return;
}
bool p=0;
while (1)
{
bool flag=0;
for (int i=x*2;i<=n-1;i+=x)
{
if (a[x]%i==0)
{
p=1;
flag=1;
swap(a[i],a[x]);
x=i;
break;
}
}
if (!flag)
break;
}
if (a[x]%x==0)
p=1;
if (!p)
cout<<"-1\n";
else
{
for (int i=1;i<=n;i++)
cout<<a[i]<<" ";
cout<<"\n";
}
}