不敲代码的意念刷题计划

CF504E Misha and LCP on Tree

题:给出一棵 n n n结点的树,每个结点上有一个字符, ( x , y ) (x,y) (x,y)表示从点 x x x到点 y y y路径上字符组成的字符串。有 q q q个查询,每个查询给出 a , b , c , d a,b,c,d a,b,c,d,求 ( a , b ) (a,b) (a,b) ( c , d ) (c,d) (c,d)的最长公共前缀。( n , q ≤ 300000 n,q\le300000 n,q300000)。
解:定义串 s s s的哈希函数为 h s ( s ) = ∑ i = 1 n ( s i − ′ 0 ′ + 1 ) ∗ b a s e i hs(s)=\sum\limits_{i=1}^n(s_i-'0'+1)*base^i hs(s)=i=1n(si0+1)basei
定义 f ( x , y ) f(x,y) f(x,y) ( x , y ) (x,y) (x,y)的哈希值。对于每一个结点 u u u,记录 f ( 1 , u ) f(1,u) f(1,u) f ( u , 1 ) f(u,1) f(u,1)。设点 s s s t t t的祖先,则 f ( s , t ) = ( f ( 1 , t ) − f ( 1 , f a s ) ) ∗ i n v ( b a s e d e p s − 1 ) f(s,t)=(f(1,t)-f(1,fa_s))*inv(base^{dep_s-1}) f(s,t)=(f(1,t)f(1,fas))inv(basedeps1) f ( t , s ) = f ( t , 1 ) − b a s e d e p t − d e p s ∗ f ( s , 1 ) f(t,s)=f(t,1)-base^{dep_t-dep_s}*f(s,1) f(t,s)=f(t,1)basedeptdepsf(s,1)同时,若 s s s t t t互不为祖先,求出其 l c a lca lca拆分出两条路径并采用,仍然可用上述方法 O ( 1 ) O(1) O(1)求出哈希值。
从而,对于每个查询,求出 l c a ( a , b ) lca(a,b) lca(a,b) l c a ( c , d ) lca(c,d) lca(c,d),二分 ( a , b ) (a,b) (a,b) ( c , d ) (c,d) (c,d)最长公共前缀的长度,长链剖分求 b b b d d d k k k级祖先,判断哈希值是否相等即可,时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)

CF505E Mr. Kitayuta vs. Bamboos

n n n朵花,第 i i i朵花最初高度为 h i h_i hi,每天晚上长高 a i a_i ai。每天白天可以使用 k k k次魔法,魔法选择一朵花 i i i,将其高度变为 m a x ( 0 , h i − p ) max(0,h_i-p) max(0,hip) m m m天后所有花中的最大高度最小是多少?
n ≤ 100000 ; m ≤ 5000 ; k ≤ 10 ; p , a i , h i ≤ 1 e 9 n\le100000;m\le5000;k\le10;p,a_i,h_i\le1e9 n100000;m5000;k10;p,ai,hi1e9

二分 m m m天后花的最大高度 H H H,判断 m m m天后花的高度是否都 ≤ H \le H H。由 h i = m a x ( 0 , h i − p ) h_i=max(0,h_i-p) hi=max(0,hip)的限制,在 h i ≤ p h_i\le p hip时,会浪费 p − h i p-h_i phi的长度,因此需要考虑尽可能少的浪费长度。
问题转换:有 n n n朵花,第 i i i朵花最初高度为 H H H,每天白天长矮 a i a_i ai。每天晚上可以使用 k k k次魔法,魔法选择一朵花 i i i,将其高度增加 p p p m m m天后花的高度是否大于 h i h_i hi?过程中花的高度要 ≥ 0 \ge0 0。每次贪心选择最快会长矮为负数的花使用魔法长高即可。
− 过 程 中 花 的 高 度 ≥ 0 的 条 件 仍 然 充 满 疑 问 中 − -过程中花的高度\ge0的条件仍然充满疑问中- 0

arc110F

给定 0 , 1 , . . . , n − 1 0,1,...,n-1 0,1,...,n1的排列 P 0 P 1 . . . P n − 1 P_0P_1...P_{n-1} P0P1...Pn1。执行交换 p i p_i pi p ( i + p i )   m o d   n p_{(i+p_i)\bmod n} p(i+pi)modn最多 200000 200000 200000次,使得排列升序。
解:先不停执行 p i = 1 p_i=1 pi=1 0 0 0交换到位置 n − 1 n-1 n1,然后把 1 , 2 , . . . , n − 1 1,2,...,n-1 1,2,...,n1逐个交换到位置 n − 2 , n − 3 , . . . , 0 n-2,n-3,...,0 n2,n3,...,0(重复交换一个位置,总是得到不同的数,但由于 0 , 1 , 2 , . . . , x 0,1,2,...,x 0,1,2,...,x被排在交换位置的 1   x + 1 1~x+1 1 x+1步中,故当 a n − x − i = x a_{n-x-i}=x anxi=x之前不会打乱顺序)。最后,将得到一个 n − 1 , n − 2 , . . . , 2 , 1 , 0 n-1,n-2,...,2,1,0 n1,n2,...,2,1,0的降序排列,此时,因为 1 1 1可以自由移动,因此对于 2 , 3 , 4 , . . . , n − 1 2,3,4,...,n-1 2,3,4,...,n1先把 1 1 1移动到对应要交换的位置,然后再进行交换。

arc109D

不敲代码的意念刷题计划_第1张图片
首先,把一个格子分成四块,每一块格子可以唯一表示一个 L L L形。
不敲代码的意念刷题计划_第2张图片
其次,观察 L L L形的移动,一个重心可以向其周围 7 7 7个位置移动(除了重心格子角的那边)。
不敲代码的意念刷题计划_第3张图片

于是可以将问题转换为重心的移动,将 L L L形转换为新棋盘中重心的坐标。观察上述移动策略可以发现,若重心坐标为 x , y x,y x,y x ≠ y x\neq y x=y,则答案为 m a x ( ∣ x ∣ , ∣ y ∣ ) max(|x|,|y|) max(x,y),否则为 ∣ x ∣ + 1 |x|+1 x+1

arc109E

首先,若两边同色,则所有方块颜色必然相同。
其次,若 [ 1 , L ] [1,L] [1,L]为白色, [ R , n ] [R,n] [R,n]为黑色,当 s − L < R − s s-LsL<Rs,则 [ 1 , R − 1 ] [1,R-1] [1,R1]为白色, [ R , n ] [R,n] [R,n]为黑色,方法是后手一直往 [ 1 , L ] [1,L] [1,L]方向跑,而先手距离 [ R , n ] [R,n] [R,n]之间必然有白色方块。反之,当 [ s − L ≥ R − s ] [s-L\ge R-s] [sLRs],则 [ 1 , L ] [1,L] [1,L]最终为白色, [ L + 1 , n ] [L+1,n] [L+1,n]最终为黑色。当 [ 1 , L ] [1,L] [1,L]为黑色, [ R , n ] [R,n] [R,n]为白色亦然。
特别地,当 s − L ≠ R − s s-L\neq R-s sL=Rs,将颜色取反具有对称性,黑白数量相等。
s − L = R − s s-L=R-s sL=Rs,由于黑色先手,当 [ 1 , L ] [1,L] [1,L]白( [ R , n ] [R,n] [R,n]黑),则 [ 1 , L ] [1,L] [1,L]白, [ L + 1 , n ] [L+1,n] [L+1,n]黑);当 [ 1 , L ] [1,L] [1,L]黑( [ R , n ] [R,n] [R,n]白), [ 1 , R − 1 ] [1,R-1] [1,R1]黑, [ R , n ] [R,n] [R,n]白,这部分单独处理即可。
这部分枚举 s s s的位置,其方案数为 ∑ i = 1 s − i > 1 , s + i < n 2 2 i \sum\limits_{i=1}^{s-i>1,s+ii=1si>1,s+i<n22i,其黑色染色数量为 ∑ i = 1 s − i > 1 , s + i < n 2 2 i − 1 ∗ ( n − ( s − i − 1 ) + s + i = n + 2 ∗ i + 1 ) = ( ( n + 1 ) ∗ ∑ i = 1 s − i > 1 , s + i < n 2 2 i − 1 ) + ( ∑ i = 1 s − i > 1 , s + i < n 2 2 i ∗ i ) \sum\limits_{i=1}^{s-i>1,s+i1,s+i1,s+ii=1si>1,s+i<n22i1(n(si1)+s+i=n+2i+1)=((n+1)i=1si>1,s+i<n22i1)+(i=1si>1,s+i<n22ii)
该式子可以通过前缀和计算,时间复杂度 O ( n ) O(n) O(n)

#include<bits/stdc++.h>//写个代码验证答案
using namespace std;
const int N=2e5+5,mod=998244353;
typedef long long ll;
int n;
ll f1[N],f2[N],f3[N];
ll qpow(ll a,ll n)
{
     
    ll ans=1;
    for(;n;n>>=1,a=a*a%mod)
        if(n&1) ans=ans*a%mod;
    return ans;
}
int main()
{
     
    scanf("%d",&n);
    if(n==1) printf("%d\n",qpow(2,mod-2));
    else
    {
     
        ll sum=qpow(2,n),isum=qpow(sum,mod-2);
        for(int i=1;i<N;i++)
        {
     
            f1[i]=(f1[i-1]+qpow(2,2*i))%mod;
            f2[i]=(f2[i-1]+qpow(2,2*i-1))%mod;
            f3[i]=(f3[i-1]+i*qpow(2,2*i)%mod)%mod;
        }
        for(int s=1;s<=n;s++)
        {
     
            if(s==1||s==2||s==n-1||s==n)
            {
     
                printf("%lld\n",1ll*n*(mod-mod/2)%mod);
                continue;
            }
            int k=min(s-2,n-s-1);//1<=i<=k
            ll ans=1ll*(sum+mod-f1[k])%mod*n%mod*isum%mod*(mod-mod/2)%mod;
            ans=(ans+(f2[k]*(n+1)%mod+f3[k])%mod*isum%mod)%mod;
            printf("%lld\n",ans);
        }
    }
}

arc108F

设直径长度为 d d d
首先,若存在两条及以上的直径,由鸽巢原理必有直径的两个端点被染成同色,答案是 d ∗ 2 n d*2^n d2n
否则,不妨令直径序列为 a 1 , a 2 , . . . , a k a_1,a_2,...,a_k a1,a2,...,ak,若 a 1 a_1 a1 a k a_k ak同色,则答案是 d d d,否则只考虑 a 1 a_1 a1白色, a k a_k ak黑色的情况(最后答案乘 2 2 2即可):
1.若 a 2 a_2 a2为黑或 a k − 1 a_{k-1} ak1为白,则答案一定是 d − 1 d-1 d1
2.若存在 ( a 2 , a k ) (a_2,a_k) (a2,ak) a 1 , a k − 1 a_1,a_{k-1} a1,ak1之外其它长度为 d − 1 d-1 d1的路径答案是 d − 1 d-1 d1
3.不存在其它路径且 a 2 a_2 a2染成白色, a k − 1 a_{k-1} ak1染成黑色,接续考虑 a 3 , a k − 2 a_3,a_{k-2} a3,ak2,依此类推,直到最后直径上剩余一个结点或不剩余结点为止。

arc108E

加入 0 , n + 1 0,n+1 0,n+1两个位置,令 f ( l , r ) f(l,r) f(l,r)表示 [ l + 1 , r − 1 ] [l+1,r-1] [l+1,r1]中首项 > l >l >l,末项 < r <r的子序列的期望长度,转移方程为 f ( l , r ) = 1 + ∑ i = 1 k ( f ( l , s i ) + f ( s i , r ) ) / k f(l,r)=1+\sum\limits_{i=1}^k(f(l,s_i)+f(s_i,r))/k f(l,r)=1+i=1k(f(l,si)+f(si,r))/k其中 l < s i , a s i < r ll<si,asi<r,线段树优化即可,巧妙之处在于扩展 0 , n + 1 0,n+1 0,n+1,使得 s i , a s i s_i,a_{s_i} si,asi的范围变得一致,且期望 D P DP DP具有可加性质。

你可能感兴趣的:(笔记)