• 题解 分手是祝愿


    whca!!!

    题目传送门

    Description

    (n) 盏初始状态为 (a_{1,2,...,n}) 的灯,在修改一个灯的状态时它的所有因子都会跟着修改,每次随机修改一个点的状态,在把剩余灯都关掉的最小操作次数 (le k) 的时候会直接采用最优方案。问期望操作次数乘上 (n!)

    (nle 10^5)

    Solution

    可以(bu neng) 想到的是,一个灯的影响不能通过其它灯组合(不包含该灯)来实现,也就是说一定是有些灯是必须要按的(或者说叫按奇数次),我们设有 (s) 个这种灯,而其它的灯按了之后必须按回来。

    那我们就可以设计状态 (f_i) 表示现在有 (i) 盏需要按的灯,把需要按的灯的数量从 (i) 变为 (i-1) 的期望操作次数。可以得到转移式:

    [f_i=frac{i}{n}+frac{n-i}{n} imes (f_{i+1}+f_i+1) ]

    (frac{i}{n}) 表示直接按到需要按的灯上去了,(frac{n-i}{n}) 意义则相反,(f_{i+1}+f_{i}+1) 表示你按错了一个灯,你就需要按回来,你还要按到 (i-1),还要加上你按错的这一次。

    移项之后就可以得到:

    [f_i=frac{n+(n-i) imes f_{i+1}}{i} ]

    边界条件就是 (f_{n+1}=0),显然你不能拿 (f_{s+1}) 作为边界条件,因为你按错了就会变成 (s+1)

    答案就是 ((sum_{i=k+1}^{s} f_i+k) imes n!)。当 (sle k) 的时候直接输出 (s) 即可。

    Code

    #include <bits/stdc++.h>
    using namespace std;
    
    #define Int register int
    #define MAXN 100005
    #define mod 100003
    
    template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
    template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
    template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
    
    int n,k,cnt,a[MAXN],f[MAXN];
    
    int mul (int a,int b){return 1ll * a * b % mod;}
    int dec (int a,int b){return a >= b ? a - b : a + mod - b;}
    int add (int a,int b){return a + b >= mod ? a + b - mod : a + b;}
    int qkpow (int a,int b){
    	int res = 1;for (;b;b >>= 1,a = mul (a,a)) if (b & 1) res = mul (res,a);
    	return res;
    }
    void Add (int &x,int y){x = add (x,y);}
    
    void makeit (int x){
    	for (Int i = 1;i * i <= x;++ i) if (x % i == 0){
    		a[i] ^= 1;
    		if (i * i != x) a[x / i] ^= 1;
    	}
    }
    
    signed main(){
    	read (n,k);
    	for (Int i = 1;i <= n;++ i) read (a[i]);
    	for (Int i = n;i >= 1;-- i) if (a[i]) makeit (i),++ cnt;
    	for (Int i = n;i >= k;-- i) f[i] = mul (add (n,mul (n - i,f[i + 1])),qkpow (i,mod - 2));
    	int ans = 0;
    	if (cnt > k){
    		for (Int i = cnt;i > k;-- i) Add (ans,f[i]);
    		Add (ans,k);
    	}
    	else ans = cnt;
    	for (Int i = 1;i <= n;++ i) ans = mul (ans,i);
    	write (ans),putchar ('
    ');
    	return 0;
    }
    
  • 相关阅读:
    [Luogu P3626] [APIO2009] 会议中心
    杭电 1869 六度分离 (求每两个节点间的距离)
    杭电 1874 畅通工程续 (求某节点到某节点的最短路径)
    最短路径模板
    杭电 2544 最短路径
    POJ 1287 Networking (最小生成树模板题)
    NYOJ 1875 畅通工程再续 (无节点间距离求最小生成树)
    POJ 2485 Highways (求最小生成树中最大的边)
    杭电 1233 还是畅通工程 (最小生成树)
    杭电 1863 畅通工程 (最小生成树)
  • 原文地址:https://www.cnblogs.com/Dark-Romance/p/14791754.html
Copyright © 2020-2023  润新知