当前位置:网站首页>2021江苏省赛A. Array-线段树,维护值域,欧拉降幂
2021江苏省赛A. Array-线段树,维护值域,欧拉降幂
2022-07-25 15:23:00 【塔子哥来了】
题目链接:
https://codeforces.com/gym/102875/problem/A
题目大意:
区间加,区间乘,区间每个数取幂,查询区间幂次和,查询区间累乘。
模数 ≤ 30 \leq 30 ≤30
题目思路:
因为模数小,那么每个数也很小。所以直接维护区间某个值 x x x的出现次数.就可以方便的回答查询。
问题在于维护修改:
由于我们转成值域问题了,所以修改一个区间等于轮换这个区间每个值。标记下放就类似于滚动数组。之后我们令 l z [ i ] lz[i] lz[i]代表 i i i要变成的数字.考虑标记如何叠加:
原本 i i i需要变到 l z [ i ] lz[i] lz[i],现在来了最新的修改方案: t r [ i ] tr[i] tr[i]
那么 i i i就变成了 t r [ l z [ i ] ] tr[lz[i]] tr[lz[i]]了.
2.一个节点不用pushdown 当且仅当三十个 l z [ i ] = i lz[i]=i lz[i]=i
然后这题线段树里快速幂会T。加欧拉降幂(注意严格遵循其公式)。然后再记忆化一下快速幂。可以过.
心得:
1.欧拉降幂需要严格按照其式子,不能擅自修改
2.打标记的时候一定要思考标记如何叠加.
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define tl (t<<1)
#define tr (t<<1|1)
#define mid ((r + l) >> 1)
#define pii pair<int,int>
#define pb push_back
#define vi vector<int>
#define vll vector<ll>
#define fi first
#define se second
const int maxn = 1e5 + 5;
const int mod = 1e9 + 7;
int sum[maxn << 2][32] , lz[maxn<<2][32] , a[maxn];
int p , n;
int phi[55] , g[55][55];
void pushup(int t)
{
for (int i = 0 ; i < p ; i++)
sum[t][i] = sum[tl][i] + sum[tr][i];
}
int mp[101][101][101];
int ksm (int a , int b , int mod){
if (a == 0) return b == 0;
if (a < 0 || a > 100 || b < 0 || b > 100 || mod < 0 || mod > 100){
cout << "gg" << endl;
exit(0);
}
if (~mp[a][b][mod]) return mp[a][b][mod];
int ans = 1 , base = a;
while (b){
if (b & 1) ans = ans * base % mod;
b >>= 1;
base = base * base % mod;
}
return ans;
}
int jm (int a , int b , int p){
if (a == 0) return b;
if (g[a][p] == 1) return b % phi[p];
if (b < phi[p]) return b;
return b % phi[p] + phi[p];
}
int tmp[50];
void D (int t , int to[32])
{
memset(tmp , 0 , sizeof tmp);
for (int i = 0 ; i < p ; i++) tmp[to[i]] += sum[t][i];
for (int i = 0 ; i < p ; i++) sum[t][i] = tmp[i];
for (int i = 0 ; i < p ; i++) lz[t][i] = to[lz[t][i]];
}
void pushdown(int t)
{
bool ok = false;
for (int i = 0 ; i < p ; i++)
if (lz[t][i] != i) ok = true;
if (!ok) return ;
D(tl,lz[t]);
D(tr,lz[t]);
for (int i = 0 ; i < p ; i++)
lz[t][i] = i;
}
void build(int l,int r,int t)
{
for (int i = 0 ; i < p ; i++) lz[t][i] = i;
if(l == r)
{
sum[t][a[l]] = 1;
return ;
}
build(l , mid , tl);
build(mid + 1 , r , tr);
pushup(t);
}
void modify(int L,int R,int l,int r, int t , int type , int c)
{
if(L <= l && r <= R)
{
int to[32]; memset(to , 0 , sizeof to);
if (type == 1)
for (int i = 0 ; i < p ; i++) {
// lz[t][i] = (lz[t][i] + c % p) % p;
to[i] = (i + c % p) % p;
}
else if (type == 2)
for (int i = 0 ; i < p ; i++) {
// lz[t][i] = (lz[t][i] * (c % p)) % p;
to[i] = (i * (c % p)) % p;
}
else
for (int i = 0 ; i < p ; i++) {
// lz[t][i] = ksm(lz[t][i] , jm(lz[t][i] , c , p) , p);
to[i] = ksm(i , jm(i , c , p) , p);
}
D(t , to);
return ;
}
pushdown(t);
if(L <= mid)
modify(L,R,l,mid,tl,type,c);
if(R > mid)
modify(L,R,mid+1,r,tr,type,c);
pushup(t);
}
int ask_power (int L,int R,int l,int r,int t , int k)
{
if(L <= l && r <= R)
{
int ans = 0;
for (int i = 0 ; i < p ; i++)
ans = (ans + sum[t][i] % p * ksm(i , jm(i , k , p) , p) % p) % p;
return ans;
}
int ans = 0;
pushdown(t);
if(L <= mid)
ans = (ans + ask_power(L,R,l,mid,tl,k)) % p;
if(R > mid)
ans = (ans + ask_power(L,R,mid+1,r,tr,k)) % p;
return ans;
}
int ask_mul (int L,int R,int l,int r,int t)
{
if(L <= l && r <= R)
{
int ans = 1;
for (int i = 0 ; i < p ; i++)
ans = (ans * ksm(i , jm(i , sum[t][i] , p) , p)) % p;
return ans;
}
int ans = 1;
pushdown(t);
if(L <= mid)
ans = (ans * ask_mul(L,R,l,mid,tl)) % p;
if(R > mid)
ans = (ans * ask_mul(L,R,mid+1,r,tr)) % p;
return ans;
}
int b[maxn];
void bf_modify (int l , int r , int t , int k){
if (t == 1){
for (int i = l ; i <= r ; i++) b[i] = (b[i] + k) % p;
}else if (t == 2){
for (int i = l ; i <= r ; i++) b[i] = (b[i] * k) % p;
}else {
for (int i = l ; i <= r ; i++) b[i] = ksm(b[i] , k , p);
}
}
int bf_ask (int l , int r , int t , int k){
int ans;
if (t == 4){
ans = 0;
for (int i = l ; i <= r ; i++) ans = (ans + ksm(b[i] , k , p)) % p;
}else if (t == 5){
ans = 1;
for (int i = l ; i <= r ; i++) ans = (ans * b[i]) % p;
}
return ans;
}
mt19937 rnd(time(0));
void getrnd (int &t , int &l , int &r , int &k){
t = rnd() % 5 + 1;
if (t == 5) k = 0;
else k = rnd() % 5000000;
l = rnd() % n + 1;
r = rnd() % n + 1;
if (l > r) swap(l , r);
}
template <typename T>
void read(T & x){
x = 0;T f = 1;char ch = getchar();while(!isdigit(ch)){
if(ch == '-') f = -1;
ch = getchar();}while (isdigit(ch)){
x = x * 10 + (ch ^ 48);ch = getchar();}x *= f;}
template <typename T>
void write(T x){
if(x < 0){
putchar('-');x = -x;}if (x > 9)write(x / 10);putchar(x % 10 + '0');}
int main()
{
memset(mp , -1 , sizeof mp);
for (int i = 2 ; i <= 30 ; i++)
for (int j = 1 ; j <= i ; j++)
if (__gcd(i , j) == 1) phi[i]++ , g[i][j] = g[j][i] = 1;
read(n);read(p);
for (int i = 1 ; i <= n ; i++){
read(a[i]);
a[i] %= p;
}
build(1 , n , 1);
int m; read(m);
int t , l , r , k;
for (int i = 1 ; i <= m ; i++){
read(t);read(l);read(r);read(k);
if (t <= 3) {
if (t <= 2) k %= p;
modify(l , r , 1 , n , 1 , t , k);
bf_modify(l , r , t , k);
}
else if (t == 4) {
int res1 = ask_power (l , r , 1 , n , 1 , k);
printf("%d\n" , res1);
}
else {
int res1 = ask_mul(l , r , 1 , n , 1);
printf("%d\n" , res1);
}
}
return 0;
}
边栏推荐
- Xcode添加mobileprovision证书文件报错:Xcode encountered an error
- Rediscluster setup and capacity expansion
- Application of C language array in Sanzi chess -- prototype of Queen n problem
- JVM-参数配置详解
- 小波变换--dwt2 与wavedec2
- How much memory can a program use at most?
- 数据系统分区设计 - 请求路由
- Spark DF增加一列
- ML - 图像 - 深度学习和卷积神经网络
- IOS interview questions
猜你喜欢
随机推荐
Spark-SQL UDF函数
Submarine cable detector tss350 (I)
Spark judges that DF is empty
Endnote 添加中文GBT7714样式 word中如何引用文献
Flex 布局
Spark AQE
SVD奇异值分解推导及应用与信号恢复
Spark submission parameters -- use of files
本地缓存--Ehcache
How to understand the maximum allowable number of errors per client connection of MySQL parameters in Seata?
Application of C language array in Sanzi chess -- prototype of Queen n problem
Understanding the execution order of T-SQL query from the execution order of join on and where
Spark SQL common time functions
No tracked branch configured for branch xxx or the branch doesn‘t exist. To make your branch trac
Iframe nested other website page full screen settings
带你详细认识JS基础语法(建议收藏)
Gbdt source code analysis of boosting
ML - 自然语言处理 - 自然语言处理简介
Find out what happened in the process of new
Idea护眼色设置









