• Codeforces Round #672


    Problems: http://codeforces.com/contest/1420


    A. Cubes Sorting


    When the array is strictly descending we need (frac{n(n-1)}{2}) operations.
    The number of operations we need is also the number of inversions in the array.

    交错代码 × 1

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    using namespace std;
    int main()
    {
    	int t, n;
    	cin>>t;
    	while(t--)
    	{
    		cin>>n;
    		int cnt=0;
    		for (register int lst=2147483647, a, i = 1; i <= n; ++i)
    		{
    			cin>>a;
    			if (a<lst) ++cnt;
    			lst=a;
    		}
    		if (cnt==n) printf("NO
    ");
    		else printf("YES
    ");
    	}
    	return 0;
    }
    


    B. Rock and Lever


    (a_i;&;a_jge a_iotimes a_j) means the highest bits in (a_i) and (a_j) are the same
    .

    用 bool 存 int × 1

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    using namespace std;
    const int MAXN = 100005;
    bool Bit[MAXN][40];
    int BitTOT[MAXN];
    long long Cnt[40];
    long long Calc(long long x)
    {
    	return (1ll*x*(x-1))>>1;
    }
    int main()
    {
    	ios::sync_with_stdio(false);
    	int t, n, ones=0, zeroes=0;
    	cin >> t;
    	while (t--)
    	{
    		for (int i = 0; i < 40; ++i) Cnt[i]=0;
    		cin >> n;
    		ones=0, zeroes=0;
    		for (register int a, i = 1; i <= n; ++i)
    		{
    			cin >> a;
    			BitTOT[i]=0;
    			while (a)
    			{
    				Bit[i][++BitTOT[i]] = a&1;
    				a>>=1;
    			}
    			++Cnt[BitTOT[i]];
    		}
    		long long Ans = 0;
    		for (int i = 0; i < 40; ++i) Ans += Calc(Cnt[i]);
    		cout<<Ans<<endl;
    	}
    	return 0;
    }
    


    C1. Pokémon Army (easy version)


    DP, choose (a_i) or not

    看错题意 × 1

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    using namespace std;
    const int MAXN = 3e5 + 10;
    int t, n, q;
    int a[MAXN];
    long long Dp[2];
    int main()
    {
    	cin >> t;
    	while (t--)
    	{
    		cin >> n >> q;
    		Dp[0]=0, Dp[1]=0; long long Tmp0=0, Tmp1=0;
    		for (register int i = 1; i <= n; ++i)
    		{
    			cin >> a[i];
    			Tmp0 = max(Dp[0], Dp[1]-a[i]);
    			Tmp1 = max(Dp[1], Dp[0]+a[i]);
    			Dp[1] = Tmp1, Dp[0] = Tmp0;
    		}
    		cout << max(Dp[1], Dp[0]) << endl;
    	}
    	return 0;
    }
    


    C2. Pokémon Army (hard version)


    一种方法是用线段树维护。复杂度带个 (log)

    当然也有 (O(n)) 做法:
    从例子入手。
    比如说:1 3 5 7 9 5 2 4 6 8 10
    显然会选择 +9 -2 +10 也就是选择了最长单调不递减序列的末尾和最长单调递减序列的末尾
    差分
    那么对于上面的例子,差分后答案是 1 + (9 - 1) + (10 - 2)
    把差分数组里面所有正数加起来,再加上 (a_1) 即可。
    交换只需稍作讨论。

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    using namespace std;
    #define DifUpdate(pos) (dif[pos] = a[pos] - a[pos-1])
    #define Recall(pos) if(dif[pos] > 0) Ans -= dif[pos]
    #define Calc(pos) if (dif[pos] > 0) Ans += dif[pos]
    const int MAXN = 3e5 + 10;
    int t, n, q;
    int a[MAXN];
    int dif[MAXN];
    long long Ans = 0;
    int main()
    {
    	ios::sync_with_stdio(false);
    	cin.tie(0); cout.tie(0);
    	cin >> t;
    	while (t--)
    	{
    		cin >> n >> q; 
    		Ans = 0;
    		for (int i = 1; i <= n; ++i)
    		{
    			cin >> a[i];
    			DifUpdate(i);
    			Calc(i);
    		}
    		cout << Ans << endl;
    		dif[0] = 0, dif[n+1] = 0;
    		a[0] = 0, a[n+1] = 0;
    		for (int qL, qR, i = 1; i <= q; ++i)
    		{
    			cin >> qL >> qR;
    			swap(a[qL], a[qR]);
    			if (qL == qR - 1)
    			{
    				Recall(qL);
    				Recall(qR);
    				Recall(qR+1);
    				DifUpdate(qL);
    				DifUpdate(qR);
    				DifUpdate(qR+1);
    				Calc(qL); 
    				Calc(qR); 
    				Calc(qR+1);
    			}
    			else
    			{
    				Recall(qL);
    				Recall(qR);
    				Recall(qL+1);
    				Recall(qR+1);
    				DifUpdate(qL);
    				DifUpdate(qR);
    				DifUpdate(qL + 1); 
    				DifUpdate(qR + 1);
    				Calc(qL);
    				Calc(qR);
    				Calc(qL+1);
    				Calc(qR+1);
    			}
    			cout << Ans << endl;
    		}
    	}
    	return 0;
    }
    


    D. Rescue Nibel!


    模拟题

    加强版:[G. Rikka with Intersections of Paths]

    场上:逆元用了ExGCD还写挂了 × 1
    没想到阶乘的逆元可以递推(不会逆元) × 1
    条件写挂了 × 1

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    using namespace std;
    const int MAXN = 3e5+10;
    int n, k, l[MAXN], r[MAXN], a[MAXN<<1];
    int Mrk[MAXN<<1], MrkSub[MAXN<<1];
    long long Ans = 0;
    long long Fact[MAXN];
    long long InvFact[MAXN];
    const long long MOD = 998244353;
    long long qpow(long long a, long long b)
    {
    	long long Ans = 1;
    	while (b)
    	{
    		if (b & 1)
    		{
    			Ans = Ans * a % MOD;
    		}
    		a = a * a % MOD;
    		b >>= 1;
    	}
    	return Ans;
    }
    long long inv(long long a)
    {
    	return qpow(a, MOD - 2);
    }
    void GetFact(int n)
    {
    	Fact[0]=1;
    	for (int i = 1; i <= n; ++i)
    	{
    		Fact[i] = Fact[i-1] * i % MOD;
    	}
    }
    long long Calc(int n, int m)
    {
    	if (n < m) return 0;
    	return Fact[n] * (InvFact[m] * InvFact[n-m] % MOD) % MOD;
    }
    void GetInvFact(int n)
    {
    //	for (int i = 0; i <= n; ++i) InvFact[i] = inv(Fact[i]);
    	InvFact[n] = inv(Fact[n]);
    	for (int i = n-1; i >= 0; --i) InvFact[i] = InvFact[i+1] * (i+1) % MOD;
    }
    int main()
    {
    //	freopen("data.in","r",stdin);
    	cin >> n >> k;
    	GetFact(n);
    	GetInvFact(n);
    	for (int i = 1; i <= n; ++i)
    	{
    		cin >> l[i] >> r[i];    ++r[i];
    		a[++a[0]]=l[i], a[++a[0]]=r[i];
    	}
    	sort(a + 1, a + 1 + a[0]);
    	a[0] = unique(a + 1, a + a[0] + 1) - a - 1;
    	for (int i = 1; i <= n; ++i)
    	{
    		l[i]=lower_bound(a + 1, a + 1 + a[0], l[i]) - a;
    		r[i]=lower_bound(a + 1, a + 1 + a[0], r[i]) - a;
    		++Mrk[l[i]], ++MrkSub[r[i]];
    	}
    	for (int tot = 0, i = 1; i <= a[0]; ++i)
    	{
    		tot -= MrkSub[i];
    NOT!!!  if (tot + Mrk[i] >= k)
    //		{
    			Ans = (Ans + MOD - Calc(tot, k)) % MOD;
    //		}
    		tot += Mrk[i];
    //		if (tot >= k) 
    //		{
    			Ans = (Ans + Calc(tot, k)) % MOD;
    //		}
    	}
    	cout << Ans;
    	return 0;
    }
    


    E. Battle Lemmings


    [看这里]

  • 相关阅读:
    C#飞行棋总结
    用python+pygame写贪吃蛇小游戏
    光线步进——RayMarching入门
    EasyX库进行图片绘制函数
    Unity复杂的旋转-欧拉角和四元数
    MATLAB GUI制作快速入门
    Three.js模型隐藏或显示
    Qt 为QPushButton、QLabel添加鼠标移入移出事件
    Unity c# 状态机的简单入门
    JavaFX Chart设置数值显示
  • 原文地址:https://www.cnblogs.com/ccryolitecc/p/13759038.html
Copyright © 2020-2023  润新知