2022河南联赛第(一)场:河南工业大学 ---复盘

A Alice and Bob — anti-Nim定理

记住定理即可

#include<iostream>
using namespace std;
#define int long long
const int N = 100010;
signed main()
{
    int x; cin >> x;
    int res = 0, f = 0; 
    for(int i = 2; i <= x / i; i ++)
    {
        if(x % i == 0)
        {
            int cnt = 0;
            while(x % i == 0)
            {
                x /= i;
                cnt ++;
            }
            if(cnt > 1) f = 1;
            res ^= cnt;
        }
    }
    if(x > 1) res ^= 1;
    if((res && f) || (!res && !f)) cout << "Alice win" << '\n';
    else cout << "Bob win\n";
}

B 打对子 — 签到

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define int long long
const int N = 1000010;
signed main()
{
	int n; cin >> n;
    string a, b; cin >> a >> b;
    sort(a.begin(), a.end());
    sort(b.begin(), b.end());
    int c1 = 0, c2 = 0;
    for(int i = 0; i < a.size(); i ++)
    {
        if(a[i] == a[i + 1])
        {
            i ++;
            continue;
        }
        c1 ++;
    }
    for(int i = 0; i < b.size(); i ++)
    {
        if(b[i] == b[i + 1])
        {
            i ++;
            continue;
        }
        c2 ++;
    }
    cout << c1 << '\n';
    if(c1 >= c2) cout << "NO" << '\n';
    else cout << "YES" << '\n';
}

C 割竿榄 — 思维贪心

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
#define int long long
const int N = 100010;
int s[N];
signed main()
{
    int n, m; cin >> n >> m;
    for(int i = 1; i <= n; i ++) cin >> s[i], s[i] += s[i - 1];
    int res = 0;
    if(3 * m >= n)
    {
        res = s[n] + (m - (n + 2) / 3) * n;
        if(n % 3) res --;
    }
    else
    {
        for(int i = 3 * m; i <= n; i ++)
            res = max(res,s[i] - s[i - 3 * m]);
    }
    for(int i = 0; i < min(m, (n + 2) / 3); i ++) res += i * 3;
    cout << res << '\n';
}
    

D 纪念品领取 — 倒着模拟

#include<iostream>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
#define int long long
const int N = 100010;
set<int>S;
int a[N], q[N];
signed main()
{
	int n, m;
    cin >> n >> m;
    for(int i = 1; i <= m; i ++) cin >> a[i];
    int idx = n;
    for(int i = m; i >= 1; i --)
    {
        if(S.count(a[i])) continue;
        S.insert(a[i]);
        q[idx --] = a[i];
    }
    idx = 0;
    for(int i = 1; i <= n; i ++)
    {
        if(S.count(i))continue;
        q[++ idx] = i;
    }
    sort(q + 1, q + 6);
    for(int i = 1; i <= 5; i ++)
        cout << q[i] << " ";
}

E 聚会 — 数学增量

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int N = 100010;
int a[N];
signed main()
{
    int n; cin >> n;
    int sum = 0;
    for(int i = 1; i <= n; i ++) cin >> a[i];
    sort(a + 1, a + n + 1);
    for(int i = 1; i <= n; i ++)
    {
        if(sum + 1< a[i]) break;
        sum += a[i];
    }
    cout << sum + 1 << '\n';    
}

F 买车 — 贪心模拟

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define int long long
const int N = 100010;
pair<int, int> a[N];
signed main()
{
	int n, m, t; cin >> n >> m >> t;
    for(int i = 1; i <= m; i ++)
        cin >> a[i].first >> a[i].second;
    sort(a + 1, a + m + 1);
    
    int sum = t, res = 0;
    for(int i = 1; i <= m; i ++)
    {
        if(sum < a[i].first || sum >= n) break;
        int j = i;
        int maxv = 0;
        
        while(j <= m && sum >= a[j].first)
        {
            maxv = max(maxv,a[j].first + a[j].second);
            j ++;
        }
        sum = maxv;
        i = j - 1;
        res ++;
    }
    if(sum < n) cout << -1 << '\n';
    else cout << res << '\n';
}

G 热身小游戏

指针写法
#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;
#define int long long
const int N = 100010,mod = 1e9 + 7;
int qmi(int a,int b){int res=1;while(b){if(b&1)res=res*a%mod;a=a*a%mod;b>>=1;}return res;}
int a[N];
int mr[N];
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
	int n; cin >> n;
    int res = 1;
    for(int i = 0; i < N; i ++)a[i]=1;
    for(int i = 1; i <= n; i ++)
    {
        int op; cin >> op;
        if(op == 1)
        {
            cin >> a[i];
            res = res * a[i] % mod;
        }
        else if(op==2)
        {
            int l, r; cin >> l >> r;
            for(int j = l; j <= r; j ++)
            {
                if(mr[j] > r)break;
                if(mr[j]) j = mr[j];
                if(a[j] == 1) continue;
                res = res * qmi(a[j], mod - 2) % mod;
                a[j] = 1;
            }
            mr[l] = max(mr[l], r + 1);
        }
        else cout << res % mod << '\n';
    }
}
线段树写法
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
#define int long long
const int N = 400010, mod = 1e9 + 7;
struct node{
    int l, r, sum, tag;
}tr[N];

void pu(int u)
{
    tr[u].sum = tr[u << 1].sum * tr[u << 1 | 1].sum % mod;
}

void pd(int u)
{
    if(tr[u].tag)
    {
        tr[u << 1].sum = 1, tr[u << 1 | 1].sum = 1;
        tr[u << 1].tag = 1, tr[u << 1 | 1].tag = 1;
        tr[u].tag = 0;
    }
}

void build(int u, int l, int r)
{
    if(l == r) tr[u] = {l, r, 1, 0};
    else
    {
        tr[u] = {l, r, 1, 0};
        int mid = l + r >> 1;
        build(u << 1, l, mid);
        build(u << 1 | 1, mid + 1, r);
        pu(u);
    }
}
void modify(int u, int l, int r, int v)
{
    if(tr[u].l >= l && tr[u].r <= r)
    {
        tr[u].sum = v;
        tr[u].tag = v;
    }
    else
    {
        pd(u);
        int mid = tr[u].l + tr[u].r >> 1;
        if(l <= mid) modify(u << 1, l, r, v);
        if(r > mid) modify(u << 1 | 1, l, r, v);
        pu(u);
    }
}


signed main()
{
    build(1,1,100000);
    int n; cin >> n;
    for(int i = 1; i <= n; i ++)
    {
        int op; cin >> op;
        if(op == 1)
        {
            int x; cin >> x;
            if(x > 1) modify(1, i, i, x);
        }
        else if(op == 2)
        {
            int l, r; cin >> l >> r;
            modify(1, l, r, 1);
        }
        else cout << tr[1].sum << '\n';
    }
}

H 兴奋值 — RMQ + 二分

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <stack>
using namespace std;
#define int long long
const int N = 100010 , mod = 1e18;


int Fmax[N][20];
int lg2[N];
int n, m;
int a[N];
void init_log()
{
    lg2[0]=-1;
    for(int i=1;i<N;i++)lg2[i]=lg2[i>>1]+1;
}
void init()
{
	for(int i=1;i<N;i++) Fmax[i][0]=a[i];
	int k=lg2[n];
	for(int j=1;j<=k;j++)
		for(int i=1;i<=n-(1<<j)+1;i++)
			Fmax[i][j]=max(Fmax[i][j-1],Fmax[i+(1<<j-1)][j-1]);
			
}
int RMQ(int l,int r)
{
	int k=lg2[r-l+1];
	int maxv=max(Fmax[l][k],Fmax[r-(1<<k)+1][k]);
	return maxv;
}

bool check(int tl, int tr, int mid)
{
    int l = tl + mid, r = tr;
    if(l > r) return true;
    int maxv = RMQ(l, r);
    return mid >= maxv;
}

signed main()
{
	cin >> n >> m;
    for(int i = 1; i <= n; i ++) cin >> a[i];
    
    init_log();
    init(); 

    for(int i = 1; i <= m; i ++) 
    {
        int tl, tr; cin >> tl >> tr;
        int l = 0, r = tr - tl + 1;
        while(l < r)
        {
            int mid = l + r >> 1;
            if(check(tl, tr, mid)) r = mid;
            else l = mid + 1;
        }
        cout << l << ' ';
    }
}

I 巡逻机器人 — 二分 + 差分

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int N = 1000010;
int n, m;
int a[N], s[N << 1];
char c[N];
bool check(int len)
{
    for(int i = 1; i <= 2 * n; i ++) s[i] = 0;
    for(int i = 1; i <= m; i ++)
    {
        if(c[i] == 'R') s[a[i]] ++,s[a[i] + len + 1] --;
        else s[a[i] + n - len] ++, s[a[i] + n + 1] --;
    }
    for(int i = 1; i <= 2 * n; i ++) s[i] += s[i - 1];
    for(int i = 1; i <= n; i ++) s[i] += s[i + n];
    for(int i = 1; i <= n; i ++) if(s[i] == 0) return false;
    return true;
}

signed main()
{
    cin >> n >> m;
    for(int i = 1; i <= m; i ++) cin >> a[i] >> c[i];
    int l = 0, r = n - 1;
    while(l < r)
    {
        int mid = l + r >> 1;
        if(check(mid)) r = mid;
        else l = mid + 1;
    }
    cout << r << '\n';
}

J 樱果运输 — 二维费用背包问题

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int N = 110, M = 1010;
int n, m;
int w[N], t[N];
int f[N][M];
signed main()
{
    cin >> n >> m;
    for(int i = 1; i <= n; i ++) cin >> w[i] >> t[i];
    
    for(int i = 1; i <= n; i ++)
    	for(int j = i; j >= 1; j --)
    		for(int k = M - 1; k >= w[i]; k --)
    			f[j][k] = max(f[j][k], f[j - 1][k - w[i]] + t[i]);

    for(int i = 1, x, y; i <= m; i ++)
    {
    	cin >> x >> y;
    	int res = -1;
    	for(int j = 1; j <= n; j ++)
    	{
    		if(f[j][x] >= y)
    		{
    			res = j;
    			break;
			}
		}
		cout << res << '\n';
	}
}

K 糟糕的一天 — 签到

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int N = 1000010;
int a[N];
signed main()
{
	int n; cin >> n;
    for(int i = 1; i <= n; i ++) cin >> a[i];
    int maxv = -2e9, res = 0;
    for(int i = n; i >= 1; i --)
    {
        if(maxv>a[i]) res ++;
        maxv = max(maxv, a[i]);
    }
    cout << res << '\n';
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_WAWA鱼_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值