UVA11916 Emoogle Grid
来源:互联网 发布:数据库权限管理 编辑:程序博客网 时间:2024/06/06 01:11
题目链接:点我
题意:
给你一个m * n的矩阵, 矩阵上有 B 个点不可填充,剩下的点填 K 种 颜色,现在给你矩阵的 N ,和 R ,R代表这个矩阵用这 K 种颜色填充共有多少种不同的方案.让你求矩阵的 N .
思路:
核心难点是大步小步算法(Baby Steps Giant Steps).首先我们先找出矩阵不能填的点的最大纵坐标maxy,然后判断以maxy 为 N 是否符合条件,如果不符合我们再判断以 maxy + 1 为 N ,判断是否符合条件,如果还是不符合,那么接下来我们算出此时以 maxy + 1 为 N 的 矩阵填充共有多少种不同的方案,然后我们知道,在 maxy + 1 的基础上 N 没增加 1 ,我们的填充方案数就应该乘以
BSGS: 先看一个式子
首先我们设 m =
代码:
#include<cstdio>#include<algorithm>#include<cstring>#include<iostream>#include<cmath>#include<map>#include<set>using namespace std;typedef long long LL;const int mod = 1e8 + 7;set<pair<int, int> > best;int x[510],y[510];LL qpow(LL x,LL n){ LL ans = 1; while(n){ if(n & 1) ans = ans * x % mod; x = x * x % mod; n >>= 1; } return ans;}void exgcd(LL a,LL b, LL &d, LL &x, LL &y){//扩展欧几里得算法求逆元, if(!b){x = 1; y = 0;d = a; return ;} exgcd(b, a %b, d, y, x); y-= a/b * x;}LL inv(LL a){ LL x, y,d; exgcd(a,mod,d,x,y); return d == 1 ? (x + mod ) % mod : -1;}int BSGS(LL x,LL r){ LL m =(LL)ceil(sqrt((double)mod+0.5)); // LL v = qpow(qpow(x,mod-2),m); LL v = inv(qpow(x,m));//经验证,两种方法都可以求得正确的逆元 map<LL,LL> q; map<LL,bool> vis; LL k = 1; vis[k] = 1; q[k] = 0; for(int i = 1; i < m; ++i){//枚举x 的次方 k = k * x % mod; if(vis[k] == 0){ vis[k] = 1; q[k] = i; } }for(int i = 0; i< m; ++i){ if(vis[r]){//如果左右两边都已经出现了,那么说明找到解. int ans = i * m +q[r]; return ans; } r =r * v % mod;//每次乘以逆元,即是在算我们上述的 x ^(- i* m) * z; } return -1;}int main(){ int t; scanf("%d", &t); int kase = 0; while(t--){ LL b, n, k, r,num; int maxx; scanf("%I64d %I64d %I64d %I64d", &n, &k, &b, &r); maxx = 1;num = 0;best.clear(); for(int i = 1; i <= b ; ++i){ scanf("%I64d %I64d", &x[i], &y[i]); maxx= max(maxx,x[i]);//找到最大的x, best.insert(make_pair(x[i],y[i])); }for(int i= 1; i <= b; ++i) if(x[i] != maxx && !best.count(make_pair(x[i]+1,y[i]))) ++num; for(int i = 1; i <= b;++i) if(x[i] == 1) --num; num += n; LL sum = (qpow(k,num) * qpow(k - 1, maxx * n - b - num) ) % mod; if (sum == r) {//判断是否符合条件, printf("Case %d: %d\n",++kase, maxx); continue; }num = 0; for(int i = 1; i <= b; ++i) if(x[i] == maxx) ++num; ++maxx; sum = sum * qpow(k-1,n-num) % mod; sum = sum * qpow(k,num) % mod; if (sum == r){ printf("Case %d: %d\n",++kase, maxx ); continue; }LL x = qpow(k-1,n); r = r *inv(sum) % mod; int ans = maxx + BSGS(x,r); printf("Case %d: %d\n",++kase,ans); }return 0;}
阅读全文
0 0
- uva11916 Emoogle Grid
- UVA11916 Emoogle Grid
- uva11916 - Emoogle Grid 网格涂色
- UVA11916 Emoogle Grid 网格涂色 大步小步算法(解模方程对数) 快速幂 模的逆 模的对数
- UVA 11916 Emoogle Grid 数论
- UVA 11916 - Emoogle Grid(数论)
- UVa11916
- UVA 11916 Emoogle Grid(离散对数)
- uva 11916 - Emoogle Grid(大步小步算法)
- UVa 11916 - Emoogle Grid (离散对数)
- [uva 11916]Emoogle Grid 数学 BSGS
- [离散对数] uva 11916 Emoogle Grid
- [离散对数] uva 11916 Emoogle Grid
- UVA - 11916 Emoogle Grid (离散对数取模)
- UVA 11916 Emoogle Grid(模指数方程)
- UVA 11916 Emoogle Grid(离散对数、BSGS算法)
- Emoogle Grid (方案数,逆元求解,对数求解)
- Emoogle Balance
- JAVA面向对象的多态性
- Echarts数据可视化全解注释
- 深度学习(入门)
- (3)2017.8.4-java基础语法和控制流程(上)
- Java中list.map.set基本概念,方法比较和遍历方式
- UVA11916 Emoogle Grid
- 对一个二维数组中的数据排序
- Java提高篇----抽象类与接口
- leetcode 220. Contains Duplicate III
- 紫书上的例题,关于BFS
- 我对指针的理解——送给即将奔赴工作岗位的小码农
- Tomcat9.0安装与配置
- JS性能优化
- centos7的防火墙