10.3爆零time

T1:

\(n!\)太大了,所以我们取\(log\)
根据\(log\)的性质,可以维护\(log_i\)的前缀和\(s_i\)
枚举\(k\)
\(s_k \geqslant s_n-s_k\)时,\(k\)满足条件

T2:

输入毒瘤哇(写了1.5h)
按照拓扑序处理

T3

语文OI题.jpg
每个字符串的长度都是\(50!\)的约数
\(n=1\)时,看看哪些位置是1

\(n!=1\):把每个位置有多少1数出来
当所有字符串长度\(\leqslant 10\)的时候,在长度为2520(1到10的最小公倍数)时一定会循环,所以可以算一个循环节内的位置,最后再算\(50!\)内有多少个位置
这是那特殊的20pts
事实上它有60pts

字符串长度为质数:
现在假设只有两个字符串。把这两个字符串都展开到它们最小公倍数的长度
煮个栗子,设第一个字符串\(p_1\)长为3,第二个字符串\(p_2\)长为5,发现\(p_1\)的第一位会和\(p_2\)的每一位都会重叠一次
就像这样(数字代表是原字符串中第几个位置)

发现\(p_1\)的1号位和\(p_2\)的所有位置都重叠过。进而发现其实\(p_1\)的每一个位置都和\(p_2\)的所有位置重叠过,这是因为所有字符串长度都互质。进而联想到乘法结合律。
我们假设\(p_1=010,p_2=10010\),那么\(p_1=\)(2个0+1个1),\(p_2=\)(3个0+2个1),类比多项式乘法,\(p_1\)\(p_2\)一共会产生6个0,7个1,2个2
发现产生的结果只和字符串中的01个数有关,与01的排列方式无关。
我们可以把所有长度相同的字符串合并起来
\(eg:010与111\)->\(121\)
然后统计合并后每个字符串数字的个数,做个乘法,可得一个循环节内的答案(乘法就像上面那样)
最后再算\(50!\)内有多少循环节,统计总答案
这样又有了20pts

100pts:
长度不互质,发现不能做到全部位置组合
这里继续用\(p_1\),\(p_2\)来表示两个字符串
既然不互质,那么\(p_1,p_2\)长度的\(gcd\)肯定大于1
\(p_1,p_2\)的长度都除以\(gcd\),那么就会互质,那么就能每个位置都重叠。那么若把长为\(gcd\)的一段字符看作一个位置,那么每个位置就都能重叠。所以我们可以把字符串分为\(\frac{len}{gcd}\)段,一段长为\(gcd\)。这样\(p_1\)每段就都会与\(p_2\)的每段都重叠过,回到互质的情况
当两个段重叠时,第一个段的第一位对应第二个段的第一位...以此类推

T4

\(n^3\)过1k
\(csp.ac\)真快鸭

\(v\)字型就是一个逆序对加上一个顺序对
暴力:\(n^5\)(但是可以拿60)(\(csp.ac\)真快鸭\(\times 2\))

优化:计算每个\(v\)被多少个区间包含
设一个\(v\)的左右端点分别是\(l,r\),则被\(l(n-r+1)\)个区间包含
\(n^3\)过1k,有了80\(pts\)

再优化:发现\(v\)字型的左右端点妹有什么关联
所以可以找左边有多少个比\(a[j]\)大的,右边有多少个比\(a[j]\)大的
计算被多少个区间包含:
设在\(a_j\)左边比\(a_j\)大的数的编号为\(i_1,i_2,...i_p\),右边为\(k_1,k_2,...,k_p\)
那么总区间数就是\(i_1(n-k_1+1)+i_1(n-k_2+1)+........+i_p(n-k_p+1)\)
合并一下就是\(\sum_i(np-\sum_k+p)\)
这样你还是有80pts

继续优化:权值线段树统计下标之和
然后你就有了100pts

posted @ 2020-10-18 17:17  千载煜  阅读(155)  评论(6编辑  收藏  举报