zoukankan      html  css  js  c++  java
  • Codeforces Round #553 (Div. 2)

    比赛链接

    cf

    A

    枚举

    #include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <set>
    using namespace std;
    const int inf = 0x3f3f3f3f;
    const int b[] = {'A' - 'A', 'C' - 'A', 'T' - 'A', 'G' - 'A'};
    char str[55];
    int n, a[55], ans = inf; 
    inline int len (int x, int y){
    	return min(abs(x - y), 26 - abs(x - y));
    }
    int main(){
    	scanf("%d%s", &n, str + 1);
    	for(int i = 1; i <= n; ++i) a[i] = str[i] - 'A';
    	for(int i = 1; i <= n - 3; ++i){
    	    int res = 0;
    	    for(int j = i; j < i + 4; ++j)
    	        res += len(a[j], b[j - i]);
    	    ans = min(ans, res);
    	}
    	printf("%d", ans);
    	return 0;
    }
    

    B

    n*m矩阵 从每一行选一个数 使得异或和不为零 (n,m leq 500)

    每行都取第一个 如果异或和为零的话 看能不能在某一行换一个不同的数
    如果有的话 那异或和一定不为零

    #include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <bitset>
    using namespace std;
    const int inf = 0x3f3f3f3f;
    int n, m, pos, val;
    bool rec[2000];
    int a[505][505];
    int main(){
    	scanf("%d%d", &n, &m);
    	for(int i = 1; i <= n; ++i)
    	    for(int j = 1; j <= m; ++j) scanf("%d", &a[i][j]);
    	int fir, pos = 0, val, sum = 0; 
    	for(int i = 1; i <= n; ++i){
    		fir = a[i][1], sum ^= fir; 
    		for(int j = 2; j <= m; ++j)
    			if(a[i][j] != fir) 
    			    pos = i, val = j;
    	}
    	if(sum | pos){
    		puts("TAK");
    		for(int i = 1; i <= n; ++i)
    		    if(!sum && pos == i) printf("%d ", val);
    		    else printf("1 ");
    	} 
    	else puts("NIE");
    	return 0;
    }
    

    C

    求[l, r]区间和 对1e9 + 7取模
    (1 / 2 4 / 3 5 7 9 / 6 8 10 12 / ... / 2^n 个连续奇数 / 2^(n + 1)个连续偶数)
    (l, r leq 1e18)

    统计[1, n]的话就算出前n个里有多少个奇数 多少个偶数
    等差数列求和加一下再做个前缀和的差

    include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <bitset>
    #define node(x, y) ((x << 1) - y)
    using namespace std;
    typedef long long ll;
    const int N = 105;
    const ll P = 1e9 + 7;
    ll L, R;
    inline ll solve(ll n){
    	ll a[2] = {}, i = 1, j = 0;
    	while(n - a[0] - a[1] > 0)
    		a[j] += min(n - a[0] - a[1], i),
    		i <<= 1, j ^= 1;
    	a[0] %= P, a[1] %= P;
    	return (a[0] * a[0] + a[1] * a[1] + a[1]) % P;
    }
    int main(){
    	scanf("%lld%lld", &L, &R);
    	printf("%lld
    ", (solve(R) + P - solve(L - 1)) % P);
    	return 0;
    }
    

    D

    长度为n的序列 每个点有两个值a[i], b[i]
    (ans = sum_{i = 1}^{i <= n} a[i] * (i - 1) + b[i] * (n - i))
    (ans_{min}) (n leq 1e5)

    这道题很国王游戏啊
    如果要交换相邻两个数i, i + 1的话
    ans = ans + a[i] - a[i + 1] - b[i] + b[i + 1]
    所以按照a[i] - b[i]排序就好啦

    #include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <bitset>
    using namespace std;
    typedef long long ll;
    const ll P = 1e9 + 7;
    const int N = 1e5 + 5;
    const int inf = 0x3f3f3f3f;
    int n, id[N];
    ll ans, a[N], b[N];
    
    inline bool rule(int x, int y){
    	return a[x] - b[x] > a[y] - b[y];//不要在比较函数里用小于等于
    }
    
    int main(){
    	scanf("%d", &n);
    	for(int i = 1; i <= n; ++i) scanf("%lld%lld", &a[i], &b[i]), id[i] = i;
    	sort(id + 1, id + n + 1, rule);
    	for(int i = 1; i <= n; ++i) ans += 1ll * a[id[i]] * (i - 1) + 1ll * b[id[i]] * (n - i);
    	printf("%lld
    ", ans);
    	return 0;
    }
    

    E

    有一个长度为n的链 每个点权值为a[]
    f(l, r)表示仅保留满足(l leq a[] leq r)的点时,有多少个连通块
    统计所有取值区间的f之和 取模1e9 + 7
    (n, a[] leq 1e5)

    考虑每个数作为区间右端点的贡献
    然后排掉左边点对它的限制

    #include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <bitset>
    #define node(x, y) ((x << 1) - y)
    using namespace std;
    typedef long long ll;
    int n; 
    ll ans;
    int main(){
    	int pre, x;
    	scanf("%d%d", &n, &pre);
    	ans += 1ll * pre * (n - pre + 1);
    	for(int i = 2; i <= n; ++i){
    		scanf("%d", &x);
    		if(pre > x) ans += 1ll * x * (pre - x);
    		else ans += 1ll * (n - x + 1) * (x - pre);
    		pre = x;
    	}
    	printf("%lld", ans); 
    	return 0;
    }
    

    F

    给定长度为n的01序列 做m次操作
    每次操作等概率选取两位置 交换两位置的值
    求m次操作结束后 序列中所有0在所有1前面的概率
    (n leq 100, m leq 1e9)

    假设一共有cnt个0
    f[i] 表示前cnt个数里有i个是0的概率
    矩阵快速幂转移即可

    竟然被一个数竞党虐了qvq菜死了

    #include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <map>
    #define P(x, y) 1ll * (x) * inv(y) % P
    using namespace std;
    typedef long long ll;
    const int N = 105;
    const ll P = 1e9 + 7;
    /*orz wjs*/
    inline ll add(ll x, ll y){
    	x += y; return x >= P ? x - P : x;
    }
    inline ll sub(ll x, ll y){
    	x -= y; return x < 0 ? x + P : x;
    }
    map<ll, ll> INV;
    inline ll inv(ll x){
    	if(!INV[x]){
    		int y = P - 2; ll res = 1;
    		while(y){
    			if(y & 1) res = res * x % P;
    			x = x * x % P; y >>= 1; 
    		}
    		INV[x] = res;
    	    //printf("inv %lld %lld
    ", x, INV[x]);
    	}
    	return INV[x];
    }
    
    struct Matrix{
    	ll w[N][N];
    	int lim;
    	void clear(int x){
    		lim = x; memset(w, 0, sizeof(w));
    	} 
    	void init(int x){
    		clear(x); for(int i = 0; i <= lim; ++i) w[i][i] = 1;
    	} 
    	friend Matrix operator * (Matrix x, Matrix y){
    		Matrix z; z.clear(x.lim);
    		for(int i = 0; i <= z.lim; ++i)
    		    for(int j = 0; j <= z.lim; ++j)
    		        for(int k = 0; k <= z.lim; ++k)
    				    z.w[i][j] = add(z.w[i][j], x.w[i][k] * y.w[k][j] % P); 
    	    return z;
    	} 
    	void print(){
    		for(int i = 0; i <= lim; ++i){
    			for(int j = 0; j <= lim; ++j)
    			    printf("%d ", w[i][j]);
    			printf("
    ");
    		}
    	}
    }beg, chg;
    int n, m, a[N], cnt;
    
    inline Matrix mpow(Matrix x, int y){
    	Matrix res; res.init(cnt);
    	while(y){
    		if(y & 1) res = res * x;
    		x = x * x; y >>= 1;
    	}
    	return res;
    }
    
    int main(){
    	scanf("%d%d", &n, &m);
    	for(int i = 1; i <= n; ++i) scanf("%d", &a[i]), cnt += (a[i] ^ 1);
    	beg.clear(cnt); chg.clear(cnt);
    	int tt = 0;
    	for(int i = 1; i <= cnt; ++i) tt += (a[i] ^ 1);
    	beg.w[tt][0] = 1;
    	for(int i = 0; i <= cnt; ++i) if(n + i >= (cnt << 1)){
    		ll c00 = i, c01 = cnt - i, c10 = cnt - i, c11 = 1ll * n - c00 - c01 - c10;
    		if(i < cnt) chg.w[i + 1][i] = P(1ll * c01 * c10 % P, 1ll * n * (n - 1) % P * inv(2) % P);
    		if(i) chg.w[i - 1][i] = P(1ll * c00 * c11 % P, 1ll * n * (n - 1) % P * inv(2) % P);
    		chg.w[i][i] = sub(1, add(chg.w[i + 1][i], chg.w[i - 1][i]));
    	}
    	Matrix res = mpow(chg, m);
    	res = res * beg;
    	printf("%lld
    ", res.w[cnt][0]);
    	return 0;
    }
    
  • 相关阅读:
    libusbwin32
    KMP
    windows.h
    iomanip
    C++继承
    LIST
    fstream
    VS2010中调试c++程序的方法
    sstream
    char 与char* 字符串与字符
  • 原文地址:https://www.cnblogs.com/hjmmm/p/10822593.html
Copyright © 2011-2022 走看看