• [Codeforces] Round #595 (Div. 3) A B1 B2 C1 C2 D1 D2 E


    A: 将数分为k组使得每组不包含数值差为1的数

    解:正整数可直接分为两组 奇数 偶数 符合题意, 所以给定数列有相邻就是2否则就是1


    B1 / B2: 给定一每个点出度为1的图问每个点走到自己需要多少步

    明显走到自己是个环, 并且环上答案都一样,递归求解即可

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 5e6 + 10;
    typedef long long ll;
    typedef long double ld;
    const ll MOD = 1e9 + 7;
    const int MX = 1e3 + 7;
    int to[MAXN] = {0};
    int ans[MAXN] = {0};
    int step = 0, fa = 0;
    void get(int now)
    {
    	int rto = to[now];
    	++step;
    	if(rto != fa)
    	{
    		get(rto);
    	}
    	ans[now] = step;
    }
    int main()
    { 
    	//ios::sync_with_stdio(0);
    	//cin.tie(0); cout.tie(0);
    	//freopen("1.txt", "r", stdin);
    	int q;
    	cin >> q;
    	while(q--)
    	{
    		int n;
    		cin >> n;
    		fill(ans, ans + n + 10, 0);
    		for(int i = 1; i <= n; ++i)
    		{
    			cin >> to[i];
    		}
    		for(int i = 1; i <= n; ++i)
    		{
    			if(!ans[i])
    			{
    				step = 0, fa = i;
    				get(i);
    			}
    		}
    		for(int i = 1; i <= n; ++i)
    		{
    			cout << ans[i] << ' ';
    		}
    		cout << '
    ';
    	}
    	
    	
        return 0;
    }

     C:问最靠近N的三进制数

    先找一个大于N的满三进制数, 从大往小贪心删除即可

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 2e6 + 10;
    typedef long long ll;
    typedef long double ld;
    const ll MOD = 1e9 + 7;
     
    ll arr[MAXN] = {1}, p = 1;
    ll pre[MAXN] = {1};
    ll a[MAXN] = {0}, pa = 0, b[MAXN] = {0}, pb = 0;
     
    int main()
    { 
    	//ios::sync_with_stdio(0);
    	//cin.tie(0); cout.tie(0);
    	//freopen("1.txt", "r", stdin);
    	for(int i = 1; ; ++i)
    	{
    		arr[p++] = arr[i - 1] * 3;
    		pre[i] = pre[i - 1] + arr[i];
    		//cout << arr[i] << ' ' << pre[i] << '
    ';
    		if(arr[i] > 1e18)
    			break;
    	}
    	int q;
    	cin >> q;
    	while(q--)
    	{
    		ll n, sum;
    		cin >> n;
    		int rp = lower_bound(pre, pre + p, n) - pre;
    		sum = pre[rp];
    		for(int i = rp; i >= 0; --i)
    		{
    			if(sum - arr[i] >= n)
    				sum -= arr[i];
    		}
    		cout << sum << '
    ';
    		
    	}
        return 0;
    }

     D1/D2: 给定一堆线段,问删最少的线段数使得每个点被覆盖最多k次

    维护一个滑窗set保存覆盖当前点的所有线段 遍历全部点更新答案

     首先当前点被覆盖多余k次 则无论如何也需要删掉当前点上的x - k条线段,这x - k条线段越往右延伸覆盖到下一个点的几率越大,所以每次碰见多k次的点,就把滑窗中最靠右的几个线段删掉并记录答案即可

    对于每个点的覆盖次数, 可以用树状数组 / 线段树维护区间加和单点查询维护

    /*
        Zeolim - An AC a day keeps the bug away
    */
     
    //#pragma GCC optimize(2)
    //#pragma GCC ("-W1,--stack=128000000")
    #include <bits/stdc++.h>
    using namespace std;
    #define mp(x, y) make_pair(x, y)
    #define fr(x, y, z) for(int x = y; x < z; ++x)
    #define pb(x) push_back(x)
    #define mem(x) memset(x, 0, sizof(x))
    typedef long long ll;
    typedef unsigned long long ull;
    typedef long double ld;
    typedef std::pair <int, int> pii;
    typedef std::vector <int> vi;
    //typedef __int128 ill;
    const ld PI = acos(-1.0);
    const ld E = exp(1.0);
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    const ll MOD = 386910137;
    const ull P = 13331; 
    const int MAXN = 2e5 + 1e4;
    const int MX = 2e5 + 10;
    int n, k;
     
    struct bit
    {
    	int c[MAXN << 1];
    	
    	int lowbit(int pos)	{return pos & -pos;}
    	void add(int pos, int val)
    	{ for( ; pos <= MX; pos += lowbit(pos)) c[pos] += val; }
    	int ask(int pos)
    	{
    		int ret = 0; 
            for( ; pos; pos -= lowbit(pos)) ret += c[pos];
    		return ret;
    	}
    };
     
    struct line
    {
    	int x, y, id;
    	bool operator < (const line b) const { return y >= b.y; }
    }lin[MAXN];
     
    bool cmp(line a, line b) { return a.x < b.x; }
     
    int main()
    { 
    	//ios::sync_with_stdio(0);
    	//cin.tie(0); cout.tie(0);
    	//freopen("1.txt", "r", stdin);
    	
    	bit T;
    	cin >> n >> k;
    	
    	for(int i = 1; i <= n; ++i)
    	{
    		int x, y;
    		cin >> x >> y;
    		lin[i] = line{x, y, i};
    		T.add(x, 1);
    		T.add(y + 1, -1);
    	}
    	sort(lin + 1, lin + n + 1, cmp);
    	vector <int> ans;
    	int p = 1;
    	set <line> ST;
    	for(int i = 1; i <= MX && p <= n; ++i)
    	{
    		int x = T.ask(i);
    		while(lin[p].x == i) { ST.insert(lin[p++]); }
    		auto it = ST.end();
    		while(ST.size() && (--it)->y < i)
    		{
    			ST.erase(it);
    			it = ST.end();
    		}
    		while(x > k)
    		{
    			it = ST.begin();
    			ans.push_back(it->id);
    			T.add(it->x, -1);
    			T.add(it->y + 1, 1);
    			ST.erase(it);
    			--x;
    		}
    	}
    	cout << ans.size() << '
    ';
    	for(auto x : ans) { cout << x << ' '; }
        return 0;
    }

     E 给两个数组 数组a是从i层到i+1层走路的时间, 数组b是从i层到i+1层坐电梯的时间,但是如果当前不在电梯里,需要等待c秒开门时间 问到达每层的最小时间

    DP[MAXN][2]代表到第i层是走楼梯 0 还是坐电梯 1 走楼梯直接转移 坐电梯转移楼梯状态就需要加c秒等待时间

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 2e6 + 10;
    typedef long long ll;
    typedef long double ld;
    const ll MOD = 1e9 + 7;
    
    ll ra[MAXN], rb[MAXN];
    ll dp[MAXN][2] = {0};
     
    int main()
    { 
    	//ios::sync_with_stdio(0);
    	//cin.tie(0); cout.tie(0);
    	//freopen("1.txt", "r", stdin);
     
    	ll n, c;
    	
    	cin >> n >> c;
    	
    	for(int i = 1; i < n; ++i)
    		cin >> ra[i];
    		
    	for(int i = 1; i < n; ++i)
    		cin >> rb[i];
    		
    	dp[0][1] = c;
    	for(int i = 1; i < n; ++i)
    	{
    		dp[i][0] = min(dp[i - 1][0] + ra[i], dp[i - 1][1] + ra[i]);
    		dp[i][1] = min(dp[i - 1][1] + rb[i], dp[i - 1][0] + rb[i] + c);
    		
    	}
    	
    	for(int i = 0; i < n; ++i)
    	{
    		cout << min(dp[i][0], dp[i][1]) << ' ';
    	}
    	
        return 0;
    }
  • 相关阅读:
    python 生成器 迭代器
    廖---高级特性 切片 迭代 列表生成式
    汉诺塔
    廖---函数
    廖---控制流
    廖---list tuple dic set
    廖---字符串和编码
    MySQL常见的三种存储引擎
    mysql悲观锁以及乐观锁总结和实践
    数据库事务的四大特性以及事务的隔离级别
  • 原文地址:https://www.cnblogs.com/zeolim/p/12270324.html
Copyright © 2020-2023  润新知