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

    Problem A

    直接暴力,当然我O(n)过的。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    #define MP		make_pair
    #define fi		first
    #define se		second
    
    
    typedef long long LL;
    
    
    int ans = 0;
    char s[205];
    int a[205], b[205];
    int n;
    
    
    int main(){
    
    
    	scanf("%s", s + 1);
    	n = strlen(s + 1);
    
    	rep(i, 1, n) if (s[i] == 'Q') a[i] = a[i - 1] + 1;
    	else a[i] = a[i - 1];
    
    	dec(i, n, 1) if (s[i] == 'Q') b[i] = b[i + 1] + 1;
    	else b[i] = b[i + 1];
    
    	rep(i, 1, n) if (s[i] == 'A') ans += a[i] * b[i];
    
    	printf("%d
    ", ans);
    
    
    	return 0;
    }
    

      

    Problem B

    打表找规律……当k为-1且n和m奇偶性不同的时候答案为0。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    #define MP		make_pair
    #define fi		first
    #define se		second
    
    
    typedef long long LL;
    
    const LL mod = 1e9 + 7;
    
    LL n, m;
    int k;
    
    inline LL Pow(LL a, LL b, LL Mod){
            LL ret(1);
            for (; b; b >>= 1, (a *= a) %= Mod) if (b & 1) (ret *= a) %= Mod;
            return ret;
    }	
    
    
    int main(){
    
    	scanf("%lld%lld%d", &n, &m, &k);
    	if (k == 1){
    		LL yy = n - 1;
    		LL hh = Pow(2, yy, mod);
    		LL ans = Pow(hh, m - 1, mod);
    		printf("%lld
    ", ans);
    	}
    
    	else{
    		LL tt = n + m;
    		if (tt % 2 == 1) return 0 * puts("0");
    		if (n % 2 == 1){
    			LL oo = (n + 1) / 2;
    			LL pp = oo - 1;
    			LL mul = Pow(16, pp, mod);
    			LL mm = m / 2;
    			LL ans = Pow(mul, mm, mod);
    			printf("%lld
    ", ans);
    		}
    
    		else{
    			LL xx = n / 2, yy = m / 2;
    			LL mul = 4 * Pow(16, xx - 1, mod) % mod;
    			LL ff = 2 * Pow(4, xx - 1, mod) % mod;
    			LL ans = ff * Pow(mul, yy - 1, mod) % mod;
    			printf("%lld
    ", ans);
    		}
    
    	}		
    
    
    	return 0;
    }
    

      

    Problem C

    构造题(赛时被X……)

    若最大的那个不能整除所有比他小的数,那么无解

    否则就按照s1,s1,s2,s1,s3,s1,s4,s1,...sn,s1这么输出。

    关键是想到。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, f)	for (int i(a); i <= (f); ++i)
    #define dec(i, a, f)	for (int i(a); i >= (f); --i)
    #define MP		make_pair
    #define fi		first
    #define se		second
    
    const int N = 1e6;
    
    
    int n;
    int c[10100];
    int f[N];
    
    int main(){
    
    	scanf("%d", &n);
    	rep(i, 1, n) scanf("%d", c + i);
    	rep(i, 2, n) if (c[i] % c[1]) return 0 * puts("-1");
    	printf("%d
    ", n << 1);
    	rep(i, 1, n) printf("%d %d
    ", c[1], c[i]);
    	putchar(10);
    }
    

      

    Problem D

    暴力存下所有点的所有儿子到他的距离。

    因为这是完全二叉树所以内存可以承受。

    空间开销$nlogn$,时间复杂度$O(nlog^{2}n)$,如果用归并排序的话那就$O(nlogn)$

    然后查询的时候一步步往上爬,把符合条件的答案统计进来。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    #define MP		make_pair
    #define fi		first
    #define se		second
    
    typedef long long LL;
    typedef pair <int, LL> PII;
    
    const int N = 1e6 + 10;
    
    int n, m;
    vector <LL > g[N], s[N];
    LL l[N], ans = 0;
    
    inline int fa(int x){ return x >> 1;}
    inline int ls(int x){ return x << 1;}
    inline int rs(int x){ return x << 1 | 1;}
    
    PII calc(int x, LL len){
    	if (len < 0) return MP(0, 0);
    	if (x > n) return MP(0, 0);
    	int sz = (int)g[x].size();
    	if (g[x][sz - 1] <= len) return MP(sz, s[x][sz - 1]);
    
    	int l = 0, r = sz - 1;
    	while (l + 1 < r){
    		int mid = (l + r) >> 1;
    		if (g[x][mid] <= len) l = mid;
    		else r = mid - 1;
    	}
    
    	int t;
    	if (g[x][r] <= len) t = r; else t = l;
    	return MP(t + 1, s[x][t]);	
    
    }
    
    void dfs(int x){
    	if (ls(x) <= n){
    		dfs(ls(x));
    		for (auto u : g[ls(x)]) g[x].push_back(l[ls(x)] + u);
    	}
    
    	if (rs(x) <= n){
    		dfs(rs(x));
    		for (auto u : g[rs(x)]) g[x].push_back(l[rs(x)] + u);
    
    	}
    
    	g[x].push_back(0);
    	sort(g[x].begin(), g[x].end());
    }
    
    int main(){
    
    	scanf("%d%d", &n, &m);
    	rep(i, 2, n) scanf("%lld", l + i);
    
    	dfs(1);
    
    	rep(i, 1, n){
    		int sz = g[i].size();
    		s[i].resize(sz + 2);
    		s[0] = g[0];
    		rep(j, 1, sz - 1) s[i][j] = s[i][j - 1] + g[i][j];
    	}
    
    	while (m--){
    		int x, y;
    		LL len, Len;
    		scanf("%d%lld", &x, &len);
    		Len = len;
    		PII cnt = calc(x, len);
    		ans = 0;
    		ans = cnt.fi * len - cnt.se;
    		y = x, x = fa(x);
    		len -= l[y];
    		while (x && len >= 0){
    			if (ls(x) == y){
    				cnt = calc(rs(x), len - l[rs(x)]);
    				ans += cnt.fi * Len - cnt.se - cnt.fi * (Len - len + l[rs(x)]);
    			}
    
    			else{
    				cnt = calc(ls(x), len - l[ls(x)]);
    				ans += cnt.fi * Len - cnt.se - cnt.fi * (Len - len + l[ls(x)]);
    			}
    
    			ans += len;
    			y = x;
    			x = fa(x);
    			len -= l[y];
    		}
    		printf("%lld
    ", ans);
    	}
    
    	return 0;
    }
    

      

    Problem E

    预处理出所有强连通分量之后缩点。

    缩成的点的权值为该点代表的强连通分量的所有边的价值和(根据题目算出来)

    然后就变成了一个DAG,DP一下就可以了。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    #define MP		make_pair
    #define fi		first
    #define se		second
    
    typedef long long LL;
    
    const int N = 1e6 + 10;
    
    vector <pair <int, int > > v[N], g[N];
    stack <int> stk;
    LL f[N], val[N];
    int n, m;
    int low[N], dfn[N], sccno[N];
    int num = 0, ti = 0;
    int s;
    
    void dfs(int x){
    	low[x] = dfn[x] = ++ti;
    	stk.push(x);
    	for (auto edge : v[x]){
    		int u = edge.fi, w = edge.se;
    		if (!low[u]){
    			dfs(u);
    			dfn[x] = min(dfn[x], dfn[u]);
    		}
    
    		else if (!sccno[u]) dfn[x] = min(dfn[x], low[u]);
    	}
    
    	if (dfn[x] == low[x]){
    		++num;
    		while (true){
    			int u = stk.top();
    			stk.pop();
    			sccno[u] = num;
    			if (u == x) break;
    		}
    	}
    }
    
    LL work(int x){
    	if (~f[x]) return f[x];
    	f[x] = 0;
    	for (auto edge : g[x]) f[x] = max(f[x], work(edge.fi) + edge.se);
    	return f[x] += val[x];
    }
    
    LL calc(int x){
    	int rt = sqrt(2 * x);
    	while ((LL)rt * (rt - 1) / 2 <= x) rt++;
    	while ((LL)rt * (rt - 1) / 2 >  x) rt--;
    	return (LL)rt * x - (LL)(rt + 1) * rt * (rt - 1) / 6;
    }
    
    int main(){
    
    	scanf("%d%d", &n, &m);
    	rep(i, 1, m){
    		int x, y, z;
    		scanf("%d%d%d", &x, &y, &z);
    		v[x].push_back(MP(y, z));
    	}
    
    	scanf("%d", &s);
    	dfs(s);
    
    	rep(i, 1, n){
    		for (auto edge : v[i]){
    			int x = i, y = edge.fi;
    			if (sccno[x] == sccno[y]) val[sccno[x]] += calc(edge.se);
    			else g[sccno[x]].push_back(MP(sccno[y], edge.se));
    		}
    	}
    
    	memset(f, -1, sizeof f);
    	printf("%lld
    ", work(sccno[s]));
    	return 0;
    }
    

      

  • 相关阅读:
    scrapy中selenium的应用
    Django的锁和事务
    redis
    【leetcode】187. Repeated DNA Sequences
    【leetcode】688. Knight Probability in Chessboard
    【leetcode】576. Out of Boundary Paths
    【leetcode】947. Most Stones Removed with Same Row or Column
    【leetcode】948. Bag of Tokens
    【leetcode】946. Validate Stack Sequences
    【leetcode】945. Minimum Increment to Make Array Unique
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/7895706.html
Copyright © 2011-2022 走看看