C.BBuBBBlesort!
一个错误的贪心:
设
a
i
a_i
ai排序后次序为
b
i
b_i
bi。
奇偶分别排序后贪心
s
w
a
p
swap
swap,然而这样排序后
a
i
a_i
ai离
b
i
b_i
bi的奇偶性会改变。
实际上只需要求出 a b s ( a i − b i ) abs(a_i-b_i) abs(ai−bi)的奇偶性即可。
D.Anticube
a
i
a_i
ai分解质因数后将每个质因子的次数模3,乘回去得到
b
i
b_i
bi。
b
i
b_i
bi就有和不能选的数一一对应。如果是同一个数,就选,否则就选数量更大的那一种数。
一个分别大小为
1
0
9
10^9
109的数的质因子的
t
r
i
c
k
trick
trick:
只需要处理
p
i
3
≤
n
p_i^3\leq n
pi3≤n的质因子,这样剩下的数只能是
p
2
p^2
p2或者
p
p
p。
E.Sequential operations on Sequence
i < j i<j i<j且 q i > q j q_i>q_j qi>qj的 i i i是无效的,单调栈维护出所有有用的 q q q。
设函数 f ( l e n , w ) f(len,w) f(len,w)表示对于长度为 l e n len len的数组每个位置的数的贡献为 w w w的处理, n u m i num_i numi表示 q i q_i qi的贡献。答案就是 ∑ f ( q i , n u m i ) \sum f(q_i,num_i) ∑f(qi,numi)。每次二分找到最大的 ≤ l e n \leq len ≤len的 q k q_k qk,将 l e n len len拆分成 q k q_k qk的整数倍和余数部分迭代下去。
不好描述,具体看代码
#include<bits/stdc++.h>
using namespace std;
#define RI register int
typedef long long LL;
LL read() {
LL q=0;char ch=' ';
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') q=q*10+(LL)(ch-'0'),ch=getchar();
return q;
}
const int N=100005;
int n,Q,top;
LL st[N],num[N],ans[N];
void work(LL len,LL s) {
int k=lower_bound(st+1,st+1+top,len)-st-1;
if(!k) {ans[1]+=s,ans[len+1]-=s;return;}
num[k]+=s*(len/st[k]),work(len%st[k],s);
}
int main()
{
LL x;
n=read(),Q=read(),st[++top]=n;
while(Q--) {
x=read();
while(top&&st[top]>x) --top;
st[++top]=x;
}
num[top]=1;
for(RI i=top;i>=1;--i) work(st[i],num[i]);
for(RI i=1;i<=n;++i) ans[i]+=ans[i-1];
for(RI i=1;i<=n;++i) printf("%lld\n",ans[i]);
return 0;
}
F.Fraction of Fractal
若存在第
i
i
i行,若
a
i
,
1
,
a
i
,
m
a_{i,1},a_{i,m}
ai,1,ai,m都为黑色的,则左右连通
若存在第
i
i
i列,若
a
1
,
i
,
a
n
,
i
a_{1,i},a_{n,i}
a1,i,an,i都为黑色的,则上下连通
设点数为 s s s
若
k
≤
1
k\leq 1
k≤1或上下左右均连通,则答案为
1
1
1。
若上下左右均不连通,则答案为
s
k
−
1
s^{k-1}
sk−1。
否则只存在上下/左右连通:
连通块个数=点数-边数
设存在
a
a
a行/列连通,且存在
b
b
b对点满足横向/纵向相邻均为黑色。
点数=
s
k
−
1
s^{k-1}
sk−1,第
i
i
i级边数
E
i
=
E
i
−
1
s
+
a
k
−
2
b
E_i=E_{i-1}s+a^{k-2}b
Ei=Ei−1s+ak−2b