2022河南联赛第(七)场:南阳理工学院 --- 复盘

A 构造? — 排列组合

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define int long long
const int N = 110, M = 10, mod = 1e9 + 7;
int qmi(int a,int b){int res=1;a=a%mod;while(b){if(b&1)res=res*a%mod;a=a*a%mod;b>>=1;}return res%mod;}
int Mod(int x){return (x%mod+mod)%mod;}
int f[M][N];
int c[N][N], pow9[N];
void init(){
    for(int i = 0; i <= 100; i ++)
    {
        for(int j = 0; j <= i; j ++)
        {
            if(!j) c[i][j] = 1;
            else c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;
        }
    }
    pow9[0] = 1;
    for(int i = 1; i <= 100; i ++) pow9[i] = pow9[i - 1] * 9 % mod;
}

int cal(int d, int n)
{
    int res = 0;
    // 首位是d
    for(int i = 0; i <= n - 1; i ++)
        res = (res + (i + 1) * d % mod * c[n - 1][i] % mod * pow9[n - i - 1] % mod) % mod;
    // 首位是 i
    for(int i = 1; i <= 9; i ++)
    {
        if(i == d) continue;
        for(int j = 0; j <= n - 1; j ++)
            res = (res + j * i % mod * c[n - 1][j] % mod * pow9[n - j - 1] % mod) % mod;
    }
    return res;
}

signed main()
{
    init();
    for(int i = 0; i <= 9; i ++)
        for(int j = 1; j <= 100; j ++)
            f[i][j] = (f[i][j - 1] + cal(i, j)) % mod;
    
    int T; cin >> T;
    while(T --)
    {
        int l, r, d; cin >> l >> r >> d;
        cout << Mod(f[d][r] - f[d][l - 1]) << '\n';
    }
}

B 龍 — 贪心

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
#define int long long

void solve()
{
	int n, a, b, x;
	cin >> n >> a >> b >> x;
    string s; cin >> s;
    int cnt = 0;
    for(int i = 0; i < s.size(); i ++)
    {
        int j = i;
        if(s[j] == '0')
        {
            cnt ++;
            while(j < n && s[j] == '0') j ++;
            i = j - 1;
        }
        
    }
    int t1 = 1e9, t2 = 1e9;
    if(cnt) t1 = a * (cnt - 1) + b;
    t2 = b * cnt;
    int res = min(t1, t2);
    if(x >= res)
    {
        cout << "Yes" << '\n';
        cout << x - res << '\n';
    }
    else cout << "No" << '\n';
    
}
signed main()
{
	int T; cin >> T;
	while(T --) solve();
}

C 机智的我 — 思维

#include <iostream>
using namespace std;
signed main()
{
    int n, k; cin >> n >> k;
	if(!k) cout << "Whatever" << '\n';
    else cout << "Why not" << '\n';
}

D 疯狂星期八 — 贪心 + dp

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define int long long
const int N = 100010;
int n, m;
int a[N], f[110];
signed main()
{
	memset(f, 0x3f, sizeof f);
	cin >> n >> m;
    for(int i = 1; i <= n; i ++) cin >> a[i];
    f[0] = 0;
	for(int i = n; i >= 1; i --)
		for(int j = 100; j > 0; j --)
			f[j] = min(f[j], f[j - 1] + a[i] + i * (j - 1));

	for(int i = 100; i >= 0; i --)
	{
		if(f[i] <= m)
		{
			cout << i << '\n';
			return 0;
		}
	}
}

E 墨笔钨丝函数 — 线段树 + 数学

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define int long long
const int N = 200010, mod = 998244753;
int qmi(int a,int b){int res=1;a=a%mod;while(b){if(b&1)res=res*a%mod;a=a*a%mod;b>>=1;}return res%mod;}
int n, m, cnt;
int w[310], p[310], a[N];
bool st[310];

struct node
{
	int l, r, state;
	int tag;	
}tr[N << 2];

void pu(int u)
{
    tr[u].state = tr[u << 1].state ^ tr[u << 1 | 1].state;
}
void pd(int u)
{
    if(tr[u].tag)
    {
        if((tr[u << 1].r - tr[u << 1].l + 1) % 2) tr[u << 1].state ^= tr[u].tag;
        if((tr[u << 1 | 1].r - tr[u << 1 | 1].l + 1) % 2) tr[u << 1 | 1].state ^= tr[u].tag;

        tr[u << 1].tag ^= tr[u].tag;
        tr[u << 1 | 1].tag ^= tr[u].tag;
        tr[u].tag = 0;

    }
}
void build(int u, int l, int r)
{
	tr[u] = {l, r};
	if(l == r) 
	{
		tr[u].state = a[l];
		return ;
	}
	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)
    {
        if((tr[u].r - tr[u].l + 1) & 1) tr[u].state ^= v;
        tr[u].tag ^= v;
        return ;
    }
    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);
}
int query(int u, int l, int r)
{
    if(tr[u].l >= l && tr[u].r <= r) return tr[u].state;
    
    int mid = tr[u].l + tr[u].r >> 1;
    pd(u);
    int res = 0;
    if(l <= mid) res ^= query(u << 1, l, r);
    if(r > mid) res ^= query(u << 1 | 1, l, r);
    return res;
}
void init()
{
    cnt = 0;
    int power = 1;
    for(int i = 2; i <= 300 ; i++)
	{
		if(!st[i])
		{ 
			w[i] = power;
			power *= 2; cnt ++;
			for(int j = i + i; j <= 300; j += i)
			{
				int t = j;
				while(t % i == 0) w[j] ^= w[i], t/= i;
				st[j] = 1;
			}
		}
	}
}
signed main() 
{
	init();
	cin >> n >> m;
    for(int i = 1; i <= n; i++ ) cin >> a[i], a[i] = w[a[i]];
    build(1, 1, n);
	while(m --)
    {
		int op, l, r; cin >> op >> l >> r;
		if(op == 1)
        {
			int x; cin >> x;
			x = w[x];
			modify(1, l, r, x);
		}
        else 
        {
            int odd = __builtin_popcountll(query(1, l, r));
            int even = cnt - odd;
            int res = qmi(3, odd) % mod * qmi(2, even) % mod;
            cout << res << '\n';
		}
	}
}

F 数对 — 树状数组

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
#define int long long
const int N = 200010;
int n,m;
vector<int> bit[110];
signed main()
{
	cin >> n >> m;
	for(int i = 1; i <= n; i ++)
	{
		int x; cin >> x;
        // 获得最高位
		for(int j = 31; j >= 1; j --)
			if((1 << (j - 1)) & x)
			{
				bit[j].push_back(i);
				break;
			}
		if(x == 0) bit[0].push_back(i);
	}
	while(m --)
	{
		int l, r; cin >> l >> r;
		int res = 0;
		for(int j = 0; j <= 31; j ++)
		{
			if(bit[j].size() < 2 || bit[j][0] > r || bit[j].back() < l) continue;
			int t1 = lower_bound(bit[j].begin(), bit[j].end(), l) - bit[j].begin();
			int t2 = upper_bound(bit[j].begin(), bit[j].end(), r) - bit[j].begin();
			res += (t2 - t1) * (t2 - t1 - 1) / 2; 
		}	
		cout << res << '\n';
	}
}
    

G 小明不希望太简单 — 构造

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
#define int long long
const int N = 200010;
int res[N];
int cnt[N];
vector<pair<int,int>> vec;
signed main()
{
	string s; cin >> s;
    int n = s.size();
    for(int i =0; i < n; i ++) cnt[s[i]-'a'] ++;
    
    for(int i = 0; i < 26; i ++) vec.push_back({cnt[i],i});
    
    sort(vec.begin(),vec.end(),greater<pair<int,int>>());
    
    vector<int> a;
    for(auto [c,x] : vec)
        while(c--)a.push_back(x);
    int j = 0;
    for(int i = 0; i < n; i += 2, j ++)
        res[i] = a[j];
    for(int i = 1; i < n; i += 2, j ++)
        res[i] = a[j];
    for(int i = 0; i < n ; i ++) cout << (char)('a' + res[i]);
}

H 防风台 — 二分

#pragma GCC optimize ("Ofast")
#pragma GCC optimize ("unroll-loops")
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
#define int long long
const int N = 1010 , mod = 1e18;
int g[N][N];
int n,m;
bool row[N],col[N];
bool check(int x)
{
    memset(row,0,sizeof row);
    memset(col,0,sizeof col);
    for(int i = 1; i <= n; i ++)
    {
        for(int j = 1; j <= m; j ++)
        {
            if(x >= g[i][j])
            {
                row[i] = 1;
                col[j] = 1;
            }
        }
    }
    for(int i = 1; i <= n; i ++) if(!row[i]) return false;
    for(int i = 1; i <= m; i ++) if(!col[i]) return false;
    return true;
}

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

I 计算几何 — 数学

#include <iostream>
using namespace std;
int main()
{
	int T; cin >> T;
    while(T --)
    {
        double a, b; cin >> a >> b;
        double res = 0;
        for(double x = -a; x <= a; x += 0.01)
            for(double y = -b; y <= b; y += 0.01)
                if(x * x / a / a + y * y / b / b <= 1 && x * x / b / b + y * y / a / a <= 1
                  && x * x + y * y + x * y <= a && x * x + y * y - x * y <= b
                  )
                res += 0.0001;
        printf("%.0lf\n", res);
    }
    
}

J 最短路— 最小生成树

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
#define int long long
const int N = 200010 , mod = 1e18;
int n, m, q, cnt;
int p[N];
struct Ed
{
    int a, b, w;
    bool operator < (const Ed &W)const
    {
        return w < W.w;
    }
}e[N];
int find(int x)
{
    if(p[x] != x) p[x] = find(p[x]);
    return p[x];
}
signed main()
{
	cin >> n >> m;
    for(int i = 0; i < m; i ++) cin >> e[i].a >> e[i].b >> e[i].w;
    sort(e,e + m);
    cin >> q;
    while(q --)
    {
        for(int i = 1; i <= n; i ++) p[i] = i;
        int x, y; cin >> x >> y;
        int res = 0;
        for(int i = 0; i < m; i ++)
        {
            int pa = find(e[i].a);
            int pb = find(e[i].b);
            if(pa != pb) p[pa] = pb;
            if(find(x) == find(y))
            {
                res = e[i].w;
                break;
            }
        }
        if(x == y) res = 0;
        cout << res << '\n';
    }
}

K 工程师CY — 二分

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define int long long
const int N = 100010;
int n, k;
int s[N];

bool check(int x)
{
	for(int i = x; i <= n; i ++)
	{
		if(s[i] - s[i - x] < k)
			return false;
	}
	return true;
}

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

L O___o___ — 数学推导

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define int long long
const int N = 200010;

void solve()
{
	double a, b, c, d;
    cin >> a >> b >> c >> d;

    int a1 = a, b1 = b, c1 = c, d1 = d;
    
    int gd1 = __gcd(a1,b1), gd2 = __gcd(c1,d1);
    a1 /= gd1, b1 /= gd1, c1 /= gd2, d1 /=gd2;
    
    if(a1 == c1 && b1 == d1 && a != c)
    {
        cout << "YES" << '\n';
        return ;
    }
    if(abs(a * d - b * c) == 1)
    {
        cout << "YES" << '\n';
        return ;
    }
    cout << "NO" << '\n';
}
signed main()
{
	int T; cin >> T;
	while(T --) solve();
}
  • 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、付费专栏及课程。

余额充值