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

    比赛链接
    cf

    A

    最后一位判定

    #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 = 65005;
    const ll P = 1e9 + 7;
    int n;
    ll ans;
    char str[N];
    int main(){
    	scanf("%d%s", &n, str + 1);
    	for(int i = 1; i <= n; ++i){
    		if(!((str[i] - '0') & 1)) ans += i;
    	}
    	printf("%lld", ans);
    	return 0;
    }
    

    B

    倒叙维护最大值

    #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 = 2e5 + 5;
    const ll P = 1e9 + 7;
    int n, a[N], lim;
    ll ans;
    int main(){
    	scanf("%d", &n);
    	for(int i = 1, x; i <= n; ++i){
    		scanf("%d", &a[i]);
    	}
    	lim = a[n]; ans += a[n];
    	for(int i = n - 1; i >= 1; --i){
    		lim = max(0, min(lim - 1, a[i]));
    		ans += lim;
    	} 
    	printf("%lld
    ", ans);
    	return 0;
    }
    

    C

    所有方案 - 全是红边的方案
    并查集维护

    #include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <map>
    #include <set>
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    const int N = 1e5 + 5;
    const ll P = 1e9 + 7;
    int n, m; ll ans;
    int size[N], fa[N];
    inline ll qpow(ll x, ll y){
    	ll res = 1;
    	while(y){
    		if(y & 1) res = res * x % P;
    		x = x * x % P; y >>= 1;
    	}
    	return res;
    }
    int find(int x){return x == fa[x] ? x : fa[x] = find(fa[x]);}
    inline void merge(int x, int y){x = find(x), y = find(y), fa[x] = y, size[y] += size[x];}
    int main(){
    	scanf("%d%d", &n, &m);
        ans = qpow(n, m);
        for(int i = 1; i <= n; ++i) fa[i] = i, size[i] = 1;
        for(int i = 1, x, y, z; i < n; ++i){
        	scanf("%d%d%d", &x, &y, &z);
        	if(!z) merge(x, y);
        }
        for(int i = 1; i <= n; ++i){
        	if(fa[i] == i){
        		ans = (ans + P - qpow(size[i], m)) % P;
        	}
        }
        printf("%lld
    ", ans); 
    	return 0;
    }
    

    然后我就自闭了?

    D

    给定数m (m leq 1e5)
    进行如下流程:
    1.rand一个[1, m]的数
    2.把它接在序列a后面
    3.如果a的gcd等于1 退出 否则进行第一步
    求进行流程次数的期望

    前面那个(frac{(m-m/x)}{m})是抽到的数不是自己的倍数的概率
    (frac{(m-m/x)}{m}*dp[x] = 1 + sum_{d|x}^{m} frac{dp[d]*c[d]}{m})
    当然容斥那里用莫比乌斯函数也ok啦【因为懒所以这么写了

    #include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <map>
    #include <set>
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    const int N = 1e5 + 5;
    const ll P = 1e9 + 7;
    inline ll qpow(ll x, ll y){
    	ll res = 1;
    	while(y){
    		if(y & 1) res = res * x % P;
    		x = x * x % P; y >>= 1;
    	}
    	return res;
    }
    int cnt[N], m, invm;
    vector<int> d[N];
    ll f[N];
    inline void init(){
    	for(int i = (m >> 1); i > 1; --i)
    		for(int j = (i << 1); j <= m; j += i)
    			d[j].push_back(i);
    	invm = qpow(m, P - 2);
    }
    inline void cut(int x){
    	for(int i : d[x]) cnt[i] -= cnt[x];
    }
    int main(){
    	scanf("%d", &m), init();
    	for(int i = 2; i <= m; ++i){
    		for(int j : d[i]) cnt[j] = m / j;
    		cnt[i] = m / i, cut(i);
    		for(int j : d[i]){
    			f[i] = (f[i] + f[j] * cnt[j] % P) % P;
    			cut(j);
    		}
    		f[i] = ((f[i] + 1ll * m) % P * qpow(m - m / i, P - 2) % P) % P;
    	}
    	ll ans = 0;
    	for(int i = 2; i <= m; ++i) ans = (ans + f[i]) % P;
    	ans = (ans * invm % P + 1) % P;
    	printf("%lld", ans);
    	return 0;
    }
    

    E

    有n个点 m个集合
    每个点有一个权值pi 有一个集合编号ci
    每次删掉一个点之后查询每个集合选一个权值的最大mex
    所有数据小于等于5000

    倒着加边 边加边匹配

    #include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <map>
    #include <set>
    #define mp(x, y) make_pair(x, y)
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    const int N = 5005;
    int n, m;
    struct Edge{int v, next;}edge[N];
    int head[N], esize;
    inline void addedge(int x, int y){
    	edge[++esize] = (Edge){y, head[x]}, head[x] = esize;
    }
    int p[N], c[N], day[N], ans;
    int d, bk[N], match[N];
    bool vis[N], del[N];
    bool dfs(int x){
    	for(int i = head[x], vv; ~i; i = edge[i].next){
    		vv = edge[i].v;
    		if(!vis[vv]){
    			vis[vv] = 1;
    			if(!match[vv] || dfs(match[vv])){
    				match[vv] = x; return 1;
    			}
    		}
    	}
    	return 0;
    }
    int main(){
    	memset(head, -1, sizeof(head));
    	scanf("%d%d", &n, &m);
    	for(int i = 1; i <= n; ++i) scanf("%d", &p[i]), ++p[i];
    	for(int i = 1; i <= n; ++i) scanf("%d", &c[i]);
    	scanf("%d", &d);
    	for(int i = 1; i <= d; ++i) scanf("%d", &bk[i]), del[bk[i]] = 1;
    	ans = 1;
    	for(int i = 1; i <= n; ++i) if(!del[i]) addedge(p[i], c[i]);
    	for(int i = d; i >= 1; --i){ 
        	memset(vis, 0, sizeof(vis));
    		while(dfs(ans)){++ans; memset(vis, 0, sizeof(vis));} 
    		day[i] = ans - 1;
    		addedge(p[bk[i]], c[bk[i]]);
    	} 
    	for(int i = 1; i <= d; ++i) printf("%d
    ", day[i]);
    	return 0;
    }
    

    F(此题解正在施工)

    让我们动手算一算
    有两个限制(原题中的inc和pref这里叫做c, f)
    (p_i leq inc_j leq s_i)
    (|b_i - f_j| leq c_j - p_i)
    第二个式子可以拆成这样
    (b_i >= f_j),那么(b_i - f_j leq c_j - p_i)
    (b_i < f_j),那么(f_j - b_i leq c_j - p_i)
    然后移位
    (b_i >= f_j),那么(b_i + p_i leq c_j + f_j)
    (b_i < f_j),那么(p_i - b_i leq c_j - f_j)
    然后把第二个式子换一下就是(b_i - p_i geq f_j - c_j)
    注意由于(c_j >= p_i),所以在(b_i < f_j时 b_i + p_i leq c_j + f_j)必然成立
    然后容斥一下就好了

    注意不要重复标记时间戳!unique的返回值十分玄学!

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 2e5 + 5;
    typedef long long ll;
    int n, m, opsize, lim;
    struct OP{
       int tim, d, tag, pos;	
    }op[N << 2];
    inline bool oprule(OP x, OP y){
    	return (x.tim == y.tim) ? (x.tag < y.tag) : (x.tim < y.tim);
    }
    vector<int> lsh;
    int p[N], s[N], b[N], c[N], f[N], ans[N];
    int id(ll x){return lower_bound(lsh.begin(), lsh.end(), x) - lsh.begin() + 1;}
    struct BIT{
        int w[N << 2];
        void mdf(int x, int d){
            x = id(x);
            while(x <= lim) w[x] += d, x += (x & -x);
    	}
        int qry(int x){
        	x = id(x); int res = 0;
        	while(x) res += w[x], x -= (x & -x);
        	return res;
        }
    }bit[2];
    int main(){
    	scanf("%d%d", &n, &m);
    	for(int i = 1; i <= n; ++i) scanf("%d", &p[i]);
    	for(int i = 1; i <= n; ++i) scanf("%d", &s[i]);
    	for(int i = 1; i <= n; ++i){
    		scanf("%d", &b[i]);
    		op[++opsize] = (OP){p[i], 1, 1, i};
    		op[++opsize] = (OP){s[i] + 1, -1, 1, i};//重复标记时间戳! 
    	}
    	for(int i = 1; i <= m; ++i) scanf("%d", &c[i]);
    	for(int i = 1; i <= m; ++i){
    		scanf("%d", &f[i]);
    		op[++opsize] = (OP){c[i], 0, 2, i};
    		lsh.push_back(c[i] + f[i]), lsh.push_back(c[i] - f[i]);
    	}
    	lsh.push_back(2e9), lsh.push_back(-2e9);
    	sort(op + 1, op + opsize + 1, oprule);
    	sort(lsh.begin(), lsh.end()); unique(lsh.begin(), lsh.end()), lim = lsh.end() - lsh.begin() + 5;//!!!
    	for(int i = 1, cnt = 0, pp; i <= opsize; ++i){
    		if(op[i].d) 
    		    cnt += op[i].d, pp = op[i].pos, 
    			bit[0].mdf(p[pp] + b[pp], op[i].d), 
    			bit[1].mdf(p[pp] - b[pp], op[i].d);
    		else pp = op[i].pos, ans[pp] = bit[0].qry(c[pp] + f[pp]) + bit[1].qry(c[pp] - f[pp]) - cnt; 
    	}
    	for(int i = 1; i <= m; ++i) printf("%d ", ans[i]);
        return 0;
    }
    
  • 相关阅读:
    【转】快速Redhat AS4和AS5升级至Centos系统
    linux 控制cpu利用率,已经远程访问linux和文件传输
    linux windows启动问题
    Skyline TEP5.1.3二次开发入门——初级(五)
    Skyline TEP5.1.3二次开发入门——初级(四)
    Skyline TEP5.1.3二次开发入门——初级(三)
    Skyline TEP5.1.3二次开发入门——初级(六)
    基于Skyline的TEP5.1.3实现对矢量SHP文件的加载和渲染
    如何在WPF中嵌入Skyline提供的三维控件
    共享一些可以通过网络访问的MPT地址
  • 原文地址:https://www.cnblogs.com/hjmmm/p/10828662.html
Copyright © 2011-2022 走看看