• 基础算法


    64位整数乘法 [https://www.acwing.com/problem/content/92/]

    sol:
    将 b 进行二进制拆分,就变成了计算$a*(2^0 + 2^1 + 2^2 +....) $,结合乘法分配律,对每一项进行相加,得到结果。 (O(logN))

    LL mul(LL a, LL b, LL p) {
    	LL res = 0;
    	for(; b; b >>= 1) {
    		if( b & 1) 
    			res = (res + a) % p;
    		a = 2 * a % p;
    	} 
    	return res;
    } 
    

    费解的开关 [https://www.acwing.com/problem/content/description/97/]

    sol:
    类似于这一道题目[https://www.luogu.com.cn/problem/CF1239A],CF的这道题是确定第一行和第一列之后所有的状态都确定了。而本题是确定了第一行的状态就
    可以推出剩下的开关状态。我却没有想到,原因是我没有考虑到一个性质,就是按开关的顺序是无关的。所以我们可以枚举第一行的所有状态,从而推出所有状态。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    
    using namespace std;
    
    const int N = 10;
    int R = 5; 
    int a[N][N], b[N][N];
    char s[N][N]; 
    
    void FilpBit(int x, int y) {
    	a[x][y] ^= 1;
    	a[x + 1][y] ^= 1;
    	a[x - 1][y] ^= 1;
    	a[x][y + 1] ^= 1;
    	a[x][y - 1] ^= 1;
    }
    
    int allLight() {
    	int cnt = 0;
    	for(int i = 2; i <= R; i ++) {
    		for(int j = 1; j <= R; j ++) {
    			if(a[i - 1][j] == 0) {
    				FilpBit(i, j);
    				cnt ++;
    		    }
    		}
    		if( i == R) {
    			for(int j = 1; j <= R; j ++) {
    				if( a[i][j] != 1)    return 7;
    			}
    		}
    	}
    	return cnt;
    } 
    
    int main()
    {
    	int T;
    	scanf("%d", &T);
    	while(T --) {
    		int ans = 7;
    		for(int i = 1; i <= R; i ++) {
    			scanf("%s", s[i] + 1);
    			for(int j = 1; j <= R; j ++) {
    				a[i][j] = s[i][j] - '0';
    				b[i][j] = a[i][j];
    			} 
    		}
    		for(int s = 0; s < (1 << R); s ++) {
    			int cnt = 0;
    			for(int k = 0; k < R; k ++) {
    				if( (s >> k) & 1) {
    					FilpBit(1, k + 1);
    					cnt ++;
    				} 
    			} 
    			ans = min(allLight() + cnt, ans);
    			memcpy(a, b, sizeof(b));
    		}
    		if( ans > 6)    ans = -1;
    		printf("%d
    ", ans);
    	}
    	return 0;
    }
    

    约数之和 [https://www.acwing.com/problem/content/99/]

    sol:
    首先利用约数个数和定理,可以得到,题目就是等比数列求和。可以用分治来解决。分类讨论,B为偶数和B为奇数。
    (f(n) = sum_{i = 0}^{n}A^i)
    再结合快速幂,f(n)就可以由f(n/2)递推过来了。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    
    using namespace std;
    
    const int N = 100, mod = 9901; 
    typedef long long LL;
    
    int p[N], cnt;
    LL r[N];
    
    void divide(int n) {
    	for(int i = 2; i * i <= n; i ++) {
    		if( n % i == 0) {
    			int t = 0;
    			p[++cnt] = i;
    			while(n % i == 0) {
    				n /= i;
    				t ++;
    			}
    			r[cnt] = t;
    		} 
    	}
    	if( n > 1) {
    		p[++cnt] = n;
    		r[cnt] = 1;
    	}
    }
    
    LL qmi(LL a, LL b) {
    	LL res = 1;
    	for(; b; b >>= 1) {
    		if(b & 1)
    			res = res * a % mod;
    		a = a * a % mod;
    	}
    	return res;
    }
    
    LL solve(LL a, LL b) {
    	if( b == 0)
    		return 1ll;
    	LL t = solve(a, b / 2);
    	if( b % 2 == 1) {
    		LL tmp = (qmi(a, (b + 1) / 2) + 1 ) * t % mod;
    		return tmp;
        } else {
        	LL tmp = ( qmi(a, b / 2) * (t - 1) % mod + t % mod) % mod;
        	return tmp;
    	}
    } 
    
    int main()
    {
    	int a, b;
    	LL ans = 1;
    	scanf("%d%d", &a, &b);
    	divide(a);
    	for(int i = 1; i <= cnt; i ++) {
    		r[i] *= b;
    		ans = ans * solve((LL)p[i], r[i]) % mod;
    	}
    	if(a == 0)
    	    ans = 0;
    	printf("%lld
    ", ans);
    	return 0;
    } 
    
  • 相关阅读:
    Linux命令行工具之pidstat命令
    Linux命令行工具之vmstat命令
    进程的状态与转换
    curl常用命令
    Linux常用命令
    TCP TIME_WAIT和CLOSE_WAIT
    OSI参考模型与TCP/IP参考模型与TCP/IP协议栈
    限流算法
    正向代理和反向代理
    oracle全量、增量备份
  • 原文地址:https://www.cnblogs.com/wyy0804/p/13619887.html
Copyright © 2020-2023  润新知