bzoj 2118: 墨墨的等式
来源:互联网 发布:美国历史人物 知乎 编辑:程序博客网 时间:2024/04/30 06:27
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2118
思路:这是一道经典问题,所以虽然不是自己想出来的还是在博客里写一下,练习了堆优化dijistra,观察,可以发现变量个数和系数范围还是比较小的,然而解的个数和规模确大到无法处理,这类问题,,,是有通法的,,,考虑,如何将解归类,也就是根据特征划分为若干集合,按集合整体快速计算,集合个数要小,单个集合计算要快O(1)或O(logn)都是可以的,也就是将解空间单射到另一个空间,往往题目中有一些数据达到了10^7以上,不看他,我们就看那些10^6以下的较小的数据,以本题为例子:发现系数很小,那么我们进行归类,每一个解都能唯一的表示为x = p*q + r的形式,也就是说形成单射,这提示我们根据余数分类,考虑,我们如果选取某个模数为p,余数为r,那么如果
x可以被如此表示,那么x + j*p都是可以的,然而我们要找最小的满足条件的x,怎么办呢,,而且是要找很多很多x,,数论走不通?图论建模,最短路模型非常简单,直接搞好了,,,
同类题目:dzy loves math 2
(未完待续)
代码:
#include<iostream>#include<cstring>#include<string>#include<cstdio>#include<algorithm>#define N 12#define M 500000#define inf 1e9using namespace std;typedef long long LL;struct edge{ int nxt,point,v; LL w;};struct data{ LL value; int id;};edge e[((N*M)<<1)+5];data heap[M+5];LL a[N+5],dis[M + 5],cnt,n,Bmin,Bmax,mini,minist;void addedge(int u1,int v1,LL w1){ e[++cnt].nxt = e[u1].point; e[u1].point = cnt; e[cnt].v = v1; e[cnt].w = w1;}//void insert(int u1,int v1){ addedge(u1,v1); addedge(v1,u1);}inline LL getnum(){ char c; LL num; while (!isdigit(c = getchar())); num = c - '0'; while (isdigit(c = getchar())) num = 10 * num + c - '0'; return num;}void init(){ n = getnum(); Bmin = getnum(); Bmax = getnum(); cnt = 0; for (int i = 1;i <= n; ++i) a[i] = getnum(); sort(a + 1,a + n + 1); mini = a[1];}void make_it(){ for (int i = 0;i < mini; ++i) for (int j = 1;j <= n; ++j) addedge(i,(i + a[j])%mini,a[j]);}inline void push(data x){ heap[++cnt] = x; int j = cnt; while (j>1&&heap[j].value < heap[(j>>1)].value) swap(heap[j],heap[j>>1]);}inline data pop(){ data x = heap[1]; heap[1] = heap[cnt--]; int j = 1; while (1){ minist = j; if ((j<<1)<=cnt) minist = j<<1; if ((j<<1|1)<=cnt&&heap[minist].value > heap[(j<<1|1)].value) minist = j<<1|1; if (minist == j) break; swap(heap[j],heap[minist]); j = minist; } return x;}void heap_dijistra(){ data tmp = (data) {0,0}; cnt = 0; memset(dis,0x7f,sizeof(dis)); dis[0] = 0; push(tmp); while (cnt){ data x = pop(); //cout<<x.id<<" "<<x.value<<endl; for (int p = e[x.id].point;p ; p = e[p].nxt) if (dis[e[p].v] > dis[x.id] + e[p].w){ dis[e[p].v] = dis[x.id] + e[p].w; push((data){dis[e[p].v],e[p].v}); } }}inline LL query(LL maxi){ if (maxi == 0) return 1; if (maxi < 0) return 0; LL sum = 0; for (int i = 0;i < mini; ++i) if (dis[i] <= maxi) sum += (maxi - dis[i])/mini + 1; return sum;}void DO_IT(){ make_it(); heap_dijistra(); //cout<<query(10)<<endl; //cout<<query(4); cout<<query(Bmax) - query(Bmin - 1);}int main(){ init(); DO_IT(); return 0;}总结:快速读入和数据该longlong就longlong,爆了很久int也没发现,,
0 0
- 【BZOJ】2118 墨墨的等式
- bzoj 2118 墨墨的等式
- bzoj 2118: 墨墨的等式
- BZOJ 2118 墨墨的等式[Waiting]
- 【BZOJ 2118】 墨墨的等式
- BZOJ 2118 墨墨的等式
- BZOJ 2118 墨墨的等式
- BZOJ 2118墨墨的等式
- BZOJ 2118 墨墨的等式
- BZOJ 2118: 墨墨的等式
- bzoj 2118 墨墨的等式 dijkstra
- BZOJ 2118 墨墨的等式 堆优化Dijkstra
- bzoj 2118: 墨墨的等式 最短路建模
- 2118: 墨墨的等式
- BZOJ 2118 墨墨的等式 最短路 同余类分析
- BZOJ-2118 墨墨的等式(好题) 最短路+乱搞
- 墨墨的等式
- 2118: 墨墨的等式 最短路
- Handler使用的那些事儿
- .dll动态文件
- Git新手上路,让你快速掌握Git的基本使用
- Creating a View Class 创建自定义视图
- 空格和tab键的vi 转换
- bzoj 2118: 墨墨的等式
- gdb调试应用程序
- 拉链法(链地址法)
- LVS DR/NAT/FULLNAT/TUNNEL模式介绍
- App.Config操作
- iOS 设置视图的圆角效果
- 数轴上一个点到其他点距离之和最小问题
- Hibernate二级缓存 的配置详解(ssh)
- EL表达式 自定义方法 tld 说明