• BZOJ2118 墨墨的等式


    Description

    传送门

    大致就是给定等式(a_{1}x_{1} + a_{2}x_{2} + a_{3}x_{3} dots + a_{n}x_{n}= B), 现在给定({a}),(B)的取值范围([B_{Min}, B_{Max}]), 求B的取值范围内有多少个B使({x})有非负整数解.

    Solution

    先进行一个简单的转化, 直接求([0, l - 1])([0,r]) 的解然后减去.就只要考虑怎么求([0, a])的答案.

    我们进行一个简单的转化, 现在给定n个物品, 每个物品有无数个,求能表示出的价值的个数.

    考虑一个数Z作为价值, 如果(l)能被Z表示为(l = kZ + D), 那么((l + z))也能被表示为((k + 1)Z + D)

    可以简单的发现(D leq Z) 于是我们考虑答案按照模(k)的剩余系分类, 然后最后计算剩余系的总和.

    (a_i)为$a_i = Min{Q}, Qmodk = i $且能被构造.那么答案就很好计算.

    我们考虑(k)怎么取值.显然,k取(min {a_i})最好, 因为它的剩余系大小最小.

    那么对于任意一个i和a[j], 我们用最短路求解, 从(i)((a_j + i) \% k),连接一条长度为(a_{j})的边.

    然后跑一遍最短路即可

    Codes

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i, a, b) for(int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
    #define drep(i, a, b) for(int i = (a), i##_end_ = (b); i >= i##_end_; --i)
    #define clar(a, b) memset((a), (b), sizeof(a))
    #define debug(...) fprintf(stderr, __VA_ARGS__)
    #define Debug(s) debug("The massage in line %d, Function %s: %s
    ", __LINE__, __FUNCTION__, s)
    typedef long long LL;
    typedef long double LD;
    const int BUF_SIZE = (int)1e6 + 10;
    struct fastIO {
        char buf[BUF_SIZE], buf1[BUF_SIZE];
        int cur, cur1;
        FILE *in, *out;
        fastIO() {
            cur = BUF_SIZE, in = stdin, out = stdout;
    		cur1 = 0;
        }
        inline char getchar() {
            if(cur == BUF_SIZE) fread(buf, BUF_SIZE, 1, in), cur = 0;
            return *(buf + (cur++));
        }
        inline void putchar(char ch) {
            *(buf1 + (cur1++)) = ch;
            if (cur1 == BUF_SIZE) fwrite(buf1, BUF_SIZE, 1, out), cur1 = 0;
        }
        inline void flush() {
            if (cur1 > 0) fwrite(buf1, cur1, 1, out);
            cur1 = 0;
        }
    }IO;
    LL read() {
    	char ch = IO.getchar();
    	LL x = 0, flag = 1;
    	for(;!isdigit(ch); ch = IO.getchar()) if(ch == '-') flag *= -1;
    	for(;isdigit(ch); ch = IO.getchar()) x = x * 10 + ch - 48;
    	return x * flag;
    }
    void write(LL x) {
    	if(x < 0) x = -x, IO.putchar('-');
    	if(x >= 10) write(x / 10);
    	IO.putchar(x % 10 + 48);
    }
    
    #define Maxn 100
    #define Maxc 1000009
    LL n, l, r, a[Maxn];
    struct edge {
    	int to, nxt, w;
    }g[Maxc * 20];
    int head[Maxc], e;
    LL Min = LLONG_MAX;
    void add(int u, int v, int w) {
    	g[++e] = (edge){v, head[u], w}, head[u] = e;
    }
    namespace SSSP {
    	struct node {
    		LL id, d;
    		int operator < (const node b) const {
    			return d > b.d;
    		}
    	};
    	LL dis[Maxc]; int vis[Maxc];
    	priority_queue <node> que;
    	void Init_Graph() {
    		clar(head, -1);
    		rep(i, 0, Min - 1)
    			rep(j, 1, n) add(i, (1ll * i + a[j]) % Min, a[j]);
    	}
    	void Dijkstra() {
    		clar(dis, 0x3f);
    		que.push((node){0, 0}); dis[0] = 0;
    		while(!que.empty()) {
    			node u = que.top(); que.pop();
    			if(vis[u.id]) continue;
    			vis[u.id] = 1;
    			for(int i = *(head + u.id); ~i; i = g[i].nxt) {
    				int v = g[i].to; 
    				if(!vis[v] && dis[v] > dis[u.id] + g[i].w) {
    					dis[v] = dis[u.id] + g[i].w;
    					que.push({v, dis[v]});
    				}
    			}
    		}
    	}
    }
    LL solve(LL a) {
    	LL ret = 0;	
    	rep(i, 0, Min - 1)
    		if(SSSP :: dis[i] <= a) 
    			ret += (a - SSSP :: dis[i]) / Min + 1;
    	return ret;
    }
    int main() {
    #ifdef Qrsikno
    	freopen("BZOJ2118.in", "r", stdin);
    	freopen("BZOJ2118.out", "w", stdout);
    #endif
    	n = read(), l = read(), r = read();
    	rep(i, 1, n) a[i] = read(), Min = min(a[i], Min);
    	SSSP :: Init_Graph();
    	SSSP :: Dijkstra();
    	write(solve(r) - solve(l - 1));	
    	IO.flush();
    	return 0;
    }
    
    

    启发

    对于一种求最小化(a_i)的值的问题,并且(a_i)可以由其他项目简单的动态的求出.可以考虑最短路求解.这事实上提供了一种建模的好方法.

    如果(a_i) 的取值范围过于大, 可以考虑按模数分类后计算, 统计答案时求和

  • 相关阅读:
    H5系列之drag拖放
    H5系列之contenteditable
    H5系列之新input
    利用css3和js实现旋转木马图片小demo
    利用css3实现照片列表展开小demo
    reduce()、filter()、map()、some()、every()、...展开属性
    ES6,ES7,ES8,ES9,ES10新特性
    Web Components 是什么?它为什么对我们这么重要?
    vscode常用快捷键以及插件
    使用for..in时会遍历对象原型中的自定义属性
  • 原文地址:https://www.cnblogs.com/qrsikno/p/9791384.html
Copyright © 2020-2023  润新知