【题解】[GenshinOI Round 3] P9816 少项式复合幂

题目链接

分析

首先这题给了很大的提示信息 注意 m 和 p 的范围 , 很自然的想到可以先把所有可能的 f ( x ) f(x) f(x) 算出来.

思维误区

有些人在算完 f ( x ) f(x) f(x) 之后可能就会去思考找环的问题,然后一些码力弱的大佬就会祭掉.

在经过仔细的观察之后 (大多数人其实一眼就看出来了罢 , 可以发现最终答案的计算是符合结合律的,或者说具有传递性? 所以考虑倍增.

令 f a [ i ] [ j ] fa[i][j] fa[i][j] 表示 f 1 < < j ( i ) f_{1<<j}(i) f1<<j(i) 的值,初始时把 f [ i ] [ 0 ] f[i][0] f[i][0] 算出来,后面就可以直接倍增了.

Code

cpp 复制代码
#include <bits/stdc++.h>
#define int long long
const int N = 1e5+10;

using namespace std;
int m,q,p;
int ksm(int a, int b){
	int ans = 1;
	while(b){
		if(b&1){
			ans = ans * a % p;
		}
		a = a*a%p;
		b >>= 1;
	}
	return ans;
}
int a[30],b[30];
int f[N];
int get(int x){
	int ans = 0;
	for(int i = 1; i <= m; i++){
		ans = (ans + a[i]*ksm(x,b[i])%p) % p;
	}
	return ans;
}
bool vis[N];
int belong[N];
vector<int> e[N];
int fa[N][30]; 
void init(){
	for(int i = 0; i < p; i++){
		fa[i][0] = get(i);
	}
	for(int i = 1;i <= 25; i++){
		for(int j = 0; j < p; j++){
			fa[j][i] = fa[fa[j][i-1]][i-1];
		}
	}
}
signed main(){
	cin >> m >> q >> p;
	for(int i = 1; i<= m; i++){
		cin >> a[i] >> b[i];
		a[i] %= p;
	} 
	init();
	while(q--){
		int x,y;
		cin >> x >> y;
		x %= p;
		for(int i = 25; i >= 0; i--){
			if((1 << i) <= y) x = fa[x][i],y -= (1<<i);
		}
		cout << x << endl;
	}
	return 0;
}
相关推荐
saltymilk2 小时前
使用 C++ 模拟 ShaderLanguage 的 swizzle
c++·模板元编程
zone77392 小时前
006:RAG 入门-面试官问你,RAG 为什么要切块?
后端·算法·面试
CoovallyAIHub5 小时前
OpenClaw 近 2000 个 Skills,为什么没有一个好用的视觉检测工具?
深度学习·算法·计算机视觉
CoovallyAIHub5 小时前
CVPR 2026 | 用一句话告诉 AI 分割什么——MedCLIPSeg 让医学图像分割不再需要海量标注
深度学习·算法·计算机视觉
CoovallyAIHub5 小时前
Claude Code 突然变成了 66 个专家?这个 5.8k Star 的开源项目,让我重新理解了什么叫"会用 AI"
深度学习·算法·计算机视觉
兆子龙6 小时前
前端哨兵模式(Sentinel Pattern):优雅实现无限滚动加载
前端·javascript·算法
xlp666hub8 小时前
Leetcode第五题:用C++解决盛最多水的容器问题
linux·c++·leetcode
CoovallyAIHub9 小时前
9个视觉语言模型工厂实测:Qwen 87.9%碾压全场,你的显卡能跑哪个?
算法
SparkX开源AI知识库10 小时前
手摸手带你安装OpenClaw并对接飞书
算法·架构
得物技术10 小时前
搜索 C++ 引擎回归能力建设:从自测到工程化准出|得物技术
c++·后端·测试