首页 > 其他分享 >「SDOI2011」计算器tj

「SDOI2011」计算器tj

时间:2023-08-21 19:22:17浏览次数:36  
标签:return int exgcd x% SDOI2011 tj 计算器 bsgs mod

你被要求设计一个计算器完成以下三项任务:
1.给定y、z、P,计算yz mod P的值
2.给定y、z、P,计算满足xy≡z(mod P)的最小非负整数x;
3.给定y、z、P,计算满足yx≡z(mod P)的最小非负整数x。

输入

第一行包含两个正整数T,K
分别表示数据组数和询问类型-对于一个测试点内的所有数据,询问类型相同。

输出

对于每个询问,输出一行答案。
对于询问类型2和3,如果不存在满足条件的x,则输出"Orz, I cannot find x!"。

数据范围

  • 20%,k=1
  • 35%,k=2
  • 45%,k=3
  • 100%,1≤y,z,P≤10^9,P为质数,1≤T≤10

思路

1.要求计算yz mod P的值,可以用快速幂来 水掉 切掉,白送的20分。
2.要求计算满足xy≡z(mod P)的最小非负整数x,简单的靠细节的同余方程,用扩展欧几里得定理求x即可
3.要求计算满足yx≡z(mod P)的最小非负整数x,这就得用到bsgs算法,专克次方,详情请见bsgs.

代码实现

1.快速幂:

函数:

int qpow(int a,int p,int mod)
{
	int t=1,x=a%mod;
	while(p)
	{
		if(p&1)
		{
			t=t*x%mod;
		}
		x=x*x%mod;
		p>>=1;
	}
	return t;
}

调用:

[略]

2.扩展欧几里得求最小解:

函数:

int exgcd(int a,int b,int &x,int &y)
{
	if(b==0)
	{
		x=1;
		y=0;
		return a;
	}
	int g=exgcd(b,a%b,y,x);
	y-=a/b*x;
	return g;
}

调用:

if(k==2)
{
	int d=exgcd(y,p,x,y);
	if(z%d!=0)
	{
		cout<<"Orz, I cannot find x!\n";
	}
	else
	{
		x=(x*z%(p/d)+p/d)%(p/d);
		cout<<x<<endl;
	}
	continue;
}

3.Bsgs:

函数:

map<int,int> mp;
int bsgs(int a,int b,int mod)
{
	mp.clear();
	if(!a)
	{
		if(!b)
		{
			return 1;
		}
		else
		{
			return -1;
		}
	}
	if(b==1)
	{
		return 0;
	}
	int bs=ceil(sqrt(mod)),ans1=1;
	for(int i=0;i<bs;i++)
	{
		mp[ans1]=i;
		ans1=ans1*a%mod;
	}
	int ans2=qpow(a,bs,mod),ans3=ans2*qpow(b,mod-2,mod)%mod;
	for(int i=1;i<=bs;i++)
	{
		if(mp[ans3]!=0)
		{
			return bs*i-mp[ans3];
		}
		ans3=ans3*ans2%mod;
	}
	return -1;
}

调用:

if(k==3)
{
	if(bsgs(y%p,z%p,p)==-1)
	{
		cout<<"Orz, I cannot find x!\n";
	}
	else
	{
		cout<<bsgs(y%p,z%p,p)<<endl;
	}
}

AC Code

#include <bits/stdc++.h>
#define int long long
using namespace std;
int t,k,x,y;
int exgcd(int a,int b,int &x,int &y)
{
	if(b==0)
	{
		x=1;
		y=0;
		return a;
	}
	int g=exgcd(b,a%b,y,x);
	y-=a/b*x;
	return g;
}
int qpow(int a,int p,int mod)
{
	int t=1,x=a%mod;
	while(p)
	{
		if(p&1)
		{
			t=t*x%mod;
		}
		x=x*x%mod;
		p>>=1;
	}
	return t;
}
map<int,int> mp;
int bsgs(int a,int b,int mod)
{
	mp.clear();
	if(!a)
	{
		if(!b)
		{
			return 1;
		}
		else
		{
			return -1;
		}
	}
	if(b==1)
	{
		return 0;
	}
	int bs=ceil(sqrt(mod)),ans1=1;
	for(int i=0;i<bs;i++)
	{
		mp[ans1]=i;
		ans1=ans1*a%mod;
	}
	int ans2=qpow(a,bs,mod),ans3=ans2*qpow(b,mod-2,mod)%mod;
	for(int i=1;i<=bs;i++)
	{
		if(mp[ans3]!=0)
		{
			return bs*i-mp[ans3];
		}
		ans3=ans3*ans2%mod;
	}
	return -1;
}
signed main()
{
	cin>>t>>k;
	while(t--)
	{
		int y,z,p;
		cin>>y>>z>>p;
		if(k==1)
		{
			cout<<qpow(y,z,p)<<endl;
			continue;
		}
		if(k==2)
		{
			int d=exgcd(y,p,x,y);
			if(z%d!=0)
			{
				cout<<"Orz, I cannot find x!\n";
			}
			else
			{
				x=(x*z%(p/d)+p/d)%(p/d);
				cout<<x<<endl;
			}
			continue;
		}
		if(k==3)
		{
			if(bsgs(y%p,z%p,p)==-1)
			{
				cout<<"Orz, I cannot find x!\n";
			}
			else
			{
				cout<<bsgs(y%p,z%p,p)<<endl;
			}
		}
	}
	return 0;
}

总结

这道题其实就是"超级板子结合体",加一点细节多读题多手玩数据就可以拿捏它。
细节耐心永远是人需要且必须的

标签:return,int,exgcd,x%,SDOI2011,tj,计算器,bsgs,mod
From: https://www.cnblogs.com/funny-cat/p/17646782.html

相关文章

  • Delphi XE UniGUI ExtJS [7] Delhi 动态添加 ClientEvents.ExtEvents 事件
    UniButton1.ClientEvents.ExtEvents.Values['click']:='function(sender){alert("Click")}';UniEdit1.ClientEvents.ExtEvents.Values['change']:='function(sender,newValue){UniForms.UniEdit2.setValue(newValue)}';Un......
  • fastjson对接口参数的某个字段不打印输出,如文件的base64字符串
    fastjson对接口参数的某个字段不打印输出,如文件的base64字符串packagecom.example.core.mydemo.json5;importcom.alibaba.fastjson.JSON;importcom.alibaba.fastjson.annotation.JSONField;/**需要提供getset方法,如果使用@Datalombok不生效(关键)**publicclassIte......
  • AOP源码解析:AspectJExpressionPointcutAdvisor类
    先看看AspectJExpressionPointcutAdvisor的类图再了解一下切点(Pointcut)表达式,它指定触发advice的方法,可以精确到返回参数,参数类型,方法名1packageconcert;23publicinterfacePerformance{4voidperform();5}AspectJExpressionPointcutAdvisor源码,官......
  • P2484 [SDOI2011] 打地鼠
    题目描述2020.4.29数据更新。打地鼠是这样的一个游戏:地面上有一些地鼠洞,地鼠们会不时从洞里探出头来很短时间后又缩回洞中。玩家的目标是在地鼠伸出头时,用锤子砸其头部,砸到的地鼠越多分数也就越高。游戏中的锤子每次只能打一只地鼠,如果多只地鼠同时探出头,玩家只能通过多次挥舞......
  • html、css、js实现的一个简单计算器
    title:html、css、js实现的一个简单计算器date:2023-07-1721:51:46categories:CTF-Web入门description:简易计算器主要代码来自runoob的计算器示例,只是精简了一下,把在js里监听完成的清除输入区也写成了一个函数,点击按钮的时候就自动调用了。这里面是有clear函数的,导致我......
  • Gson与FastJson详解
    Gson与FastJson详解Java与JSON做什么?将Java中的对象快速的转换为JSON格式的字符串.将JSON格式的字符串,转换为Java的对象.Gson将对象转换为JSON字符串转换JSON字符串的步骤:引入JAR包在需要转换JSON字符串的位置编写如下代码即可:Stringjson=newGson().toJSON(要转换的对象......
  • [18章]Vue3+NestJS 全栈开发企业级管理后台
    点击下载:[18章]Vue3+NestJS全栈开发企业级管理后台提取码:zzbv Next.js是一个用于构建现代化React应用程序的框架。它强调性能、开发体验和SEO优化,是许多React开发者的首选。Next.js提供了许多功能,包括:服务器渲染:Next.js允许在服务器端渲染React应用程序,从而提高了应......
  • 7维空间计算器kwl2024下载
    2024版更新记录: 2024EditionupdateRecord:1、能计算一些7维空间的距离和角度的数据。2、能建立、保存和打开数据定义文件和结果文件。1,cancomputethedataof7dimssomedistancesofspacesandangle.2,cancreate,keepandopendocumentandresultdocument......
  • Python小项目:利用tkinter搭建个人所得税计算器
    文章目录1前言2详细介绍3代码介绍4结语完整项目下载:下载链接1前言在当今数字化时代,个人所得税的计算对于每个人来说都是一个重要而复杂的任务。为了让个人所得税的计算变得更加便捷和直观,本实验采用了Python编程语言,并借助tkinter图形化界面库,搭建了一个实用的个人所得......
  • fastjson反序列化 TODO
    参考链接fastjson反序列化入门文章https://tttang.com/archive/1579/https://xz.aliyun.com/t/12096ASM动态加载相关,如何查看内存生成的类的源码https://juejin.cn/post/6974566732224528392#heading-6https://blog.csdn.net/wjy160925/article/details/85288569关闭ASM去......