• 洛谷 NOIP 2023 模拟赛 挑战 NPC IV


    洛谷 NOIP 2023 模拟赛 挑战 NPC IV

    题目大意

    f ( x ) = 1 + log ⁡ 2 lowbit ( x ) f(x)=1+\log_2\text{lowbit}(x) f(x)=1+log2lowbit(x),对于一个 1 1 1 n n n的排列 p i p_i pi,其权值 ∑ l = 1 n ∑ r = l n ∑ i = l r f ( p i ) \sum\limits_{l=1}^n\sum\limits_{r=l}^n\sum\limits_{i=l}^rf(p_i) l=1nr=lni=lrf(pi)。求一个 1 1 1 n n n的排列 p i p_i pi,使得这个排列是所有排列中第 k k k小的。输出第 k k k小的权值模 998244353 998244353 998244353后的值。

    q q q组数据。

    测试点编号 n n n k ≤ k \leq k q = q= q=
    1 ∼ 3 1 \sim 3 13 ≤ 10 \leq 10 10 n ! n! n! 2 2 2
    4 ∼ 8 4 \sim 8 48 ≤ 1 0 3 \leq 10^3 103 2 2 2 7 7 7
    9 ∼ 13 9 \sim 13 913 ∈ [ 1 0 5 , 1 0 6 ] \in [10^5, 10^6] [105,106] min ⁡ ( 1 0 18 , n ! ) \min(10^{18}, n!) min(1018,n!) 7 7 7
    14 ∼ 17 14 \sim 17 1417 ≤ 1 0 6 \leq 10^6 106 min ⁡ ( 1 0 18 , n ! ) \min(10^{18}, n!) min(1018,n!) 7 7 7
    18 ∼ 25 18 \sim 25 1825 ≤ 1 0 18 \leq 10^{18} 1018 min ⁡ ( 1 0 18 , n ! ) \min(10^{18}, n!) min(1018,n!) 10 10 10

    对于 100 % 100\% 100% 的数据,保证 1 ≤ n ≤ 1 0 18 1 \leq n \leq 10^{18} 1n1018 1 ≤ k ≤ min ⁡ ( 1 0 18 , n ! ) 1 \leq k \leq \min(10^{18}, n!) 1kmin(1018,n!) 1 ≤ q ≤ 10 1 \leq q\le 10 1q10

    时间限制为 max ⁡ ( q × 0.5 , 2 ) s \max(q\times 0.5, 2)s max(q×0.5,2)s,空间限制为 512 M B 512MB 512MB


    题解

    首先,我们可以得出, ∑ l = 1 n ∑ r = l n ∑ i = l r f ( p i ) = ∑ i = 1 n f ( p i ) × i × ( n − i + 1 ) \sum\limits_{l=1}^n\sum\limits_{r=l}^n\sum\limits_{i=l}^rf(p_i)=\sum\limits_{i=1}^nf(p_i)\times i\times (n-i+1) l=1nr=lni=lrf(pi)=i=1nf(pi)×i×(ni+1)。记 c i = i × ( n − i + 1 ) c_i=i\times (n-i+1) ci=i×(ni+1) d i = f ( p i ) d_i=f(p_i) di=f(pi)

    我们先考虑 k = 1 k=1 k=1的情况,也就是要最小化 c i × d i c_i\times d_i ci×di的和,我们用最大的 c c c值来匹配最小的 d d d值,次大的 c c c值来匹配次小的 d d d值,以此类推。

    k = 2 k=2 k=2时,我们在权值最小的排列 p i p_i pi的基础上,交换 p 1 p_1 p1 p n p_n pn的位置,权值不变,也就是说 k = 2 k=2 k=2时的答案与 k = 1 k=1 k=1的时的答案相同。

    k = 2 k=2 k=2的情况的启发下,我们发现:

    • p i p_i pi p j p_j pj的最低位 1 1 1的位置相同,则交换 p i p_i pi p j p_j pj不会改变权值
    • 交换 p i p_i pi p n − i + 1 p_{n-i+1} pni+1也不会改变权值

    我们推测:权值取到最小值的排列有很多。

    事实上,当 n = 29 n=29 n=29时,这样的排列数量就已经超过了 1 0 18 10^{18} 1018,所以,当 n ≥ 29 n\geq 29 n29时,答案与 k k k无关,始终为最小的权值。

    如果按上面那样做是 O ( n ) O(n) O(n)的,下面考虑优化。

    对于每一种 f f f值,我们需要查询 c c c值从小到大排序后一段区间的和,推式子即可,时间复杂度是 O ( log ⁡ n ) O(\log n) O(logn)的。

    n ≤ 28 n\leq 28 n28时,我们可以用 D P DP DP来做。

    f [ a ] [ b ] [ c ] [ d ] [ e ] [ s ] f[a][b][c][d][e][s] f[a][b][c][d][e][s]表示目前已经填了前 i = a + b + c + d + e i=a+b+c+d+e i=a+b+c+d+e个数,其中有 a a a个数的最低位为 1 1 1 b b b个数的最低位为 2 2 2,以此类推,且当前的权值为 s s s

    我们枚举下一个位置的最低位 1 1 1的位置 t t t,那么新状态的权值为 s + c i + 1 × t s+c_{i+1}\times t s+ci+1×t

    我们发现,从最低位 1 1 1的位置为 1 1 1 5 5 5的数的数量分别为 14 , 7 , 4 , 2 , 1 14,7,4,2,1 14,7,4,2,1,还要算上 0 0 0的情况,最大的权值不会超过 10000 10000 10000,那么总状态数 S S S不超过 15 × 8 × 5 × 3 × 2 × 10000 = 3.6 × 1 0 7 15\times 8\times 5\times 3\times 2\times 10000=3.6\times 10^7 15×8×5×3×2×10000=3.6×107,那么 D P DP DP的时间复杂度为 O ( 5 S ) O(5S) O(5S)

    总时间复杂度为 O ( q ( log ⁡ n + 5 S ) ) O(q(\log n+5S)) O(q(logn+5S))

    code

    #include
    using namespace std;
    const int N=30,V=10000;
    const long long mod=998244353;
    const long long ny2=499122177,ny6=166374059;
    int T,c[N+5],w[10];
    long long n,k,ans,lst,now,f[15][8][5][3][2][V+5];
    long long gt2(long long t){
    	t%=mod;
    	return t*(t+1)%mod*ny2%mod;
    }
    long long gt6(long long t){
    	t%=mod;
    	return t*(t+1)%mod*(2*t+1)%mod*ny6%mod;
    }
    long long gt(long long t){
    	long long re=(t&1)*(t/2+1)%mod*((n-(t/2+1)+1)%mod)%mod;t/=2;
    	long long tmp=((n+1)%mod*gt2(t)%mod-gt6(t)+mod)%mod;
    	re=(re+tmp*2)%mod;
    	return re;
    }
    void pt(long long *a,long long *b,int t,int p){
    	for(int i=0;i<=V;i++){
    		if(b[i]) a[i+t]+=b[i]*p;
    	}
    }
    void gt(long long *a){
    	for(int i=0;i<=V;i++){
    		if(k>a[i]) k-=a[i];
    		else{
    			printf("%d\n",i);
    			return;
    		}
    	}
    }
    int main()
    {
    	scanf("%d",&T);
    	while(T--){
    		scanf("%lld%lld",&n,&k);
    		ans=0;
    		if(n>=29){
    			lst=now=0;
    			for(int i=60;i>=1;i--){
    				now=lst+(n+(1ll<<i-1))/(1ll<<i);
    				ans=(ans+(gt(now)-gt(lst)+mod)%mod*i%mod)%mod;
    				lst=now;
    			}
    			printf("%lld\n",ans);
    			continue;
    		}
    		for(int i=1;i<=n;i++){
    			c[i]=i*(n-i+1);
    		}
    		for(int i=1;i<=5;i++){
    			w[i]=(n+(1<<i-1))/(1<<i);
    		}
    		memset(f,0,sizeof(f));
    		f[0][0][0][0][0][0]=1;
    		for(int v1=0;v1<=w[1];v1++)
    		for(int v2=0;v2<=w[2];v2++)
    		for(int v3=0;v3<=w[3];v3++)
    		for(int v4=0;v4<=w[4];v4++)
    		for(int v5=0;v5<=w[5];v5++){
    			int sum=v1+v2+v3+v4+v5;
    			if(v1<w[1]) pt(f[v1+1][v2][v3][v4][v5],f[v1][v2][v3][v4][v5],c[sum+1]*1,w[1]-v1);
    			if(v2<w[2]) pt(f[v1][v2+1][v3][v4][v5],f[v1][v2][v3][v4][v5],c[sum+1]*2,w[2]-v2);
    			if(v3<w[3]) pt(f[v1][v2][v3+1][v4][v5],f[v1][v2][v3][v4][v5],c[sum+1]*3,w[3]-v3);
    			if(v4<w[4]) pt(f[v1][v2][v3][v4+1][v5],f[v1][v2][v3][v4][v5],c[sum+1]*4,w[4]-v4);
    			if(v5<w[5]) pt(f[v1][v2][v3][v4][v5+1],f[v1][v2][v3][v4][v5],c[sum+1]*5,w[5]-v5);
    		}
    		gt(f[w[1]][w[2]][w[3]][w[4]][w[5]]);
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
  • 相关阅读:
    化工行业调研:有机硅胶市场现状及规模分析
    three.js入门 ---- 相机控件OrbitControls
    mysql根据条件导出表数据(`--where=“文本“`)
    JetpackCompose从入门到实战学习笔记2——Modifier的简单使用
    18 | 注解和反射
    操作系统内存管理-01分段
    opencv边缘-边界处理
    2022/09/04 day01:Linux背景
    【AGC】集成华为AGC崩溃服务实用教程
    Spring Boot 整合SpringSecurity和JWT和Redis实现统一鉴权认证
  • 原文地址:https://blog.csdn.net/tanjunming2020/article/details/134428466