2022河南联赛第三场:河南大学 ---复盘

A 玉米大炮 — 二分

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int N = 200010;
int n, m;
int a[N], b[N];
bool check(int mid)
{
    int res = 0;
    for(int i = 1; i <= n; i ++)
    {
        res += a[i] * (int)(mid / b[i]) + a[i];
        if(res >= m) return true;
    }
    return res >= m;
}

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

B 逆序对计数 — 预处理 + 树状数组

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int N = 6010;
int n, q;
int tr[N], a[N];
int f[N][N];
int lowbit(int x)
{
    return x & -x;
}
void add(int x, int v)
{
    for(int i = x; i <= n; i += lowbit(i)) tr[i] += v;
}
int query(int x)
{
    int res = 0;
    for(int i = x; i; i -= lowbit(i)) res += tr[i];
    return res;
}
signed main()
{
    cin >> n;
    for(int i = 1; i <= n; i ++) cin >> a[i];
    for(int i = 1; i <= n; i ++)
    {
        for(int j = i; j <= n; j ++)
        {
            
            f[i][j] = f[i][j - 1] + query(n) - query(a[j]);
            add(a[j], 1);
        }
        for(int j = 0; j <= n; j ++) tr[j] = 0;
    }
    int sum = f[1][n];
    cin >> q;
    while(q --)
    {
        int l, r; cin >> l >> r;
        int res = sum - f[l][r] + (r - l + 1) * (r - l) / 2 - f[l][r];
        cout << res << '\n';
    }
}

C 区间操作 — 线段树 + 线性筛

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<cmath>
#include<set>
using namespace std;
#define int long long
const int N=4000010;
int b[N];
int primes[N], idx = 0, f[N];
bool st[N];
struct node
{
	int l, r, sum;
	int add;	
}tr[N << 2];

void init(int n){
	for(int i = 2 ; i <= n ; i ++){
		if(!st[i]) primes[idx ++] = i, f[i] = 1;
		for(int j = 0; primes[j] * i <= n; j ++)
        {
			st[i * primes[j]] = 1 ;
			f[i * primes[j]] = f[i] + 1;
			if(i % primes[j] == 0) break;
		}
	}
}

void pushup(node &u, node &l, node &r)
{
	u.sum = l.sum + r.sum;
}

void pushup(int u)
{
	pushup(tr[u], tr[u << 1], tr[u << 1 | 1]);
}

void pushdown(int u)
{
	if(tr[u].add)
	{
		tr[u << 1].sum += tr[u].add * (tr[u << 1].r - tr[u << 1].l + 1);
		tr[u << 1 | 1].sum += tr[u].add * (tr[u << 1 | 1].r - tr[u << 1 | 1].l + 1);
		
		tr[u << 1].add += tr[u].add;
		tr[u << 1 | 1].add += tr[u].add;
		tr[u].add = 0;
		
	}
}

void build(int u, int l, int r)
{
	tr[u] = {l, r};
	if(l == r) 
	{
		tr[u].sum = b[l];
		return ;
	}
	int mid = l + r >> 1;
	build(u << 1, l, mid);
	build(u << 1 | 1, mid + 1, r);
	pushup(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].r - tr[u].l + 1);
		tr[u].add += v;
		return;
	} 
	pushdown(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);
	pushup(u);
}

int query(int u, int l, int r)
{
	if(tr[u].l >= l && tr[u].r <= r) return tr[u].sum;
	
	int res = 0;
	int mid = tr[u].l + tr[u].r >> 1;
	pushdown(u);
	if(l <= mid) res += query(u << 1, l, r);
	if(r > mid) res += query(u << 1 | 1, l, r);
	return res;
}

signed main()
{
	ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    init(N - 1);
    int n; cin >> n;
    for(int i = 1; i <= n; i ++) cin >> b[i], b[i] = f[b[i]];
    
    build(1, 1, n);
    
    int q; cin >> q;
    while(q --)
    {
    	int op, l , r;
    	cin >> op >> l >> r;
    	if(op == 1) cout << query(1, l, r) << '\n';
    	else
    	{
    		int x; cin >> x;
    		modify(1, l, r, f[x]);
		}
	}
}

D 小蓝的新技能 — 数学优化暴力

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

signed main()
{
    int n; cin >> n;
    int res = 0;
    // (a,b)最大公因数
    for(int gcd = 1; gcd * gcd * gcd <= n; gcd ++)
    {
        // a
        for(int a = gcd; a * a * a <= n; a += gcd)
        {
            int lcm3 = n - gcd * gcd * gcd;
            
            int l = 1, r = 1e6;
            while(l < r)
            {
                int mid = l + r >> 1;
                if(mid * mid * mid >= lcm3) r = mid;
                else l = mid + 1;
            }
            
            if(r * r * r != lcm3) continue; 
            int lcm = r;
            int b = lcm * gcd / a;
            if( __gcd(a, b) == gcd && a * b == lcm * gcd) res ++;
            
        }
    }
    cout << res << '\n';
}

F 爱学习的小蓝—签到

#include<iostream>
#include<cstring> 
using namespace std;
#define int long long
const int N = 100010;
int a[10] = {2, 8, 8, 18, 18, 32, 32};
void solve()
{
    int x; cin >> x;
    int res = 0;
    for(int i = 0; i < 8; i ++)
    {
        if(res >= x)
        {
            cout << i << '\n';
            return ;
        }
        res += a[i];
    }
}

signed main()
{
	int T; cin >> T;
    while(T --) solve();
}

H 树上问题 — 树形dp

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define int long long
const int N = 100010, M = 4000000;
int n;
int a[N], down[N], up[N];
vector<int> g[N];
int res = 0;
void dfs1(int u, int fa)
{
    int maxv = 0;
    for(auto v : g[u])
    {
        if(v == fa) continue;
        dfs1(v, u);
        maxv = max(maxv, down[v]);
    }
    down[u] = maxv + a[u];
}

void dfs2(int u, int fa)
{
    int d1 = 0, d2 = 0;
    for(auto v : g[u])
    {
        if(v == fa) continue;
        if(down[v] >= d1)
        {
            d2 = d1;
            d1 = down[v];
        }
        else if(down[v] > d2) d2 = down[v];
    }
    
    for(auto v : g[u])
    {
        if(v == fa) continue;
        if(down[v] == d1)
            up[v] = max({up[v], up[u] + a[v], d2 + a[u] + a[v]});
        else 
            up[v] = max({up[v], up[u] + a[v], d1 + a[u] + a[v]});
        dfs2(v, u);
    }
}

int f[N];
void dfs3(int u, int fa)
{
    int m1 = 0, m2 = 0;
    int maxv = 0;
    for(auto v : g[u])
    {
        if(v == fa) continue;
        dfs3(v, u);
        int t = max(up[v], down[v]);
        if(t >= m1)
        {
            m2 = m1;
            m1 = t;
        }
        else if(t > m2) m2 = t;
        maxv = max(maxv, f[v]);
    }
    f[u] = m1 + max(down[u], up[u]);
    res = max({res, m1 + m2 + max(down[u], up[u]), maxv + max(down[u], up[u])});
}

signed main()
{
    cin >> n;
    for(int i = 1; i <= n; i ++) cin >> a[i];
    for(int i = 1; i < n; i ++)
    {
        int u, v; cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs1(1, -1);
    dfs2(1, -1);
    dfs3(1, -1);
    cout << res << '\n';
}

I 旅行—最短路

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
#define int long long
typedef pair<int, int>PII;
const int N = 400010, M = 4000000;
vector<PII> g[N];
int n, m, x;
int dist[N];
bool st[N];
int dij()
{
    memset(dist, 0x3f, sizeof dist);
    dist[1] = 0;
    priority_queue<PII, vector<PII>, greater<PII> >heap;
    heap.push({0,1});
    while(heap.size())
    {
        auto [dis,u] = heap.top();
        heap.pop();
        if(st[u]) continue;
        st[u] = true;
        for(auto [v, w] : g[u])
        {
            if(dist[v] > dist[u] + w)
            {
                dist[v] = dist[u] + w;
                heap.push({dist[v], v});
            }
        }
        
    }
    return min(dist[n], dist[n + n]);
}
signed main()
{
    cin >> n >> m >> x;
    for(int i = 1; i <= m; i ++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        g[a + n].push_back({b, c});
        g[b + n].push_back({a, c});
        g[a].push_back({b + n, c + x});
        g[b].push_back({a + n, c + x});
    }
    cout << dij() << '\n';
}

J 神奇数字—数学

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

void solve()
{
	int a[3];
	cin >> a[0] >> a[1] >> a[2];
	
	if(a[0] == a[1] && a[1] == a[2])
	{
		cout << -1 << '\n';
		return ;
	}
	
	sort(a, a + 3);
	int n = __gcd(a[2] - a[1], a[1] - a[0]);
	vector<int>res;
	for(int i = 1; i <= n / i; i ++)
	{
		if(n % i == 0)
		{
			res.push_back(i);
			if(n != i * i) res.push_back(n / i);
		}
	}
    sort(res.begin(), res.end());
	for(auto x : res) cout << x << ' ';
    cout << '\n';
}

signed main()
{
	int T; cin >> T;
	while(T --) solve();
}

L 合成游戏 — 数学

#include<iostream>
using namespace std;
#define int long long
const int N = 100010, mod = 1e9 + 7;
int n;
int a[N], f[N], g[N];
signed main(){
	cin >> n;
	f[1] = f[2] = 1;
	for(int i = 3; i <= n; i ++)
    {
		if(i % 2 == 1) f[i] = i * f[i-1] % mod;
		else f[i] = f[i - 2] * (i - 1) % mod;
	}
	g[1] = g[2] = 1;
	for(int i = 3; i <= n; i ++)
		g[i] = f[i] * g[i / 2] % mod;
	for(int i = 1; i <= n; i ++)
    {
		int x; cin >> x;
		cout << g[x] << '\n';
	}
}

相关文章

学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习...
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面...
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生...
Can’t connect to local MySQL server through socket \'/v...
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 ...
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服...