看似数学题实则数据结构(线段树)——数学计算

时间:2020-05-28
本文章向大家介绍看似数学题实则数据结构(线段树)——数学计算,主要包括看似数学题实则数据结构(线段树)——数学计算使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

小豆现在有一个数x,初始值为1. 小豆有Q次操作,操作有两种类型:
1 m: x = x * m ,输出 x%mod;
2 pos: x = x / 第pos次操作所乘的数(保证第pos次操作一定为类型1,对于每一个类型1 的操作至多会被除一次),输出x%mod

一共有t组输入(t ≤ 5)
对于每一组输入,第一行是两个数字Q, mod(Q ≤ 100000, mod ≤ 1000000000);
接下来Q行,每一行为操作类型op,操作编号或所乘的数字m(保证所有的输入都是合法的).
1 ≤ Q ≤ 100000
———————————————

——————————

如何解决:

考虑用线段树,操作一就在操作的位置插入m,操作二就是把第pos位贡献变为1,这样求区间乘积就可以了

——————————————————————————————————

——————————————

代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
#define ll long long
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
const int maxn=200005;
int treee[maxn<<2],mod;
int read(){
int x=0,v=1; char ch=getchar();
for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar());
for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());
return x*v;
}
void modify(int now,int tl,int tr,int x,int v){
if (tl==tr) return (void) (treee[now]=v);
int mid=(tl+tr)>>1;
if (x<=mid) modify(now<<1,tl,mid,x,v);
else modify(now<<1|1,mid+1,tr,x,v);
treee[now]=1LL*treee[now<<1]*treee[now<<1|1]%mod;
}
int query(int now,int tl,int tr,int l,int r) {
if (r<l) return 1;
if (tl>=l&&tr<=r) return treee[now];
int mid=(tl+tr)>>1;
int qx=query(now<<1,tl,mid,l,std:: min(r,mid));
int qy=query(now<<1|1,mid+1,tr,std:: max(mid+1,l),r);
return 1LL*qx*qy%mod;
}
void build(int now,int tl,int tr) {
treee[now]=1;
if (tl==tr) return ;
int mid=(tl+tr)>>1;
build(now<<1,tl,mid);
build(now<<1|1,mid+1,tr);
}
int main(){
//freopen("a.in","r",stdin);
for (int T=read();T--;) {
int n=read(); mod=read();
build(1,1,n);
rep(i,1,n){
int opt=read(),x=read();
if(opt==1)modify(1,1,n,i,x);
else modify(1,1,n,x,1);
printf("%d\n", treee[1]);
}
}
return 0;
}

代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
#define ll long long
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
const int maxn=200005;
int treee[maxn<<2],mod;
int read(){
    int x=0,v=1; char ch=getchar();
    for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar());
    for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());
    return x*v;
}
void modify(int now,int tl,int tr,int x,int v){
    if (tl==tr) return (void) (treee[now]=v);
    int mid=(tl+tr)>>1;
    if (x<=mid) modify(now<<1,tl,mid,x,v);
    else modify(now<<1|1,mid+1,tr,x,v);
    treee[now]=1LL*treee[now<<1]*treee[now<<1|1]%mod;
}
int query(int now,int tl,int tr,int l,int r) {
    if (r<l) return 1;
    if (tl>=l&&tr<=r) return treee[now];
    int mid=(tl+tr)>>1;
    int qx=query(now<<1,tl,mid,l,std:: min(r,mid));
    int qy=query(now<<1|1,mid+1,tr,std:: max(mid+1,l),r);
    return 1LL*qx*qy%mod;
}
void build(int now,int tl,int tr) {
    treee[now]=1;
    if (tl==tr) return ;
    int mid=(tl+tr)>>1;
    build(now<<1,tl,mid);
    build(now<<1|1,mid+1,tr);
}
int main(){
    //freopen("a.in","r",stdin);
    for (int T=read();T--;) {
        int n=read(); mod=read();
        build(1,1,n);
        rep(i,1,n){
            int opt=read(),x=read();
            if(opt==1)modify(1,1,n,i,x);
            else modify(1,1,n,x,1);
            printf("%d\n", treee[1]);
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/DZN2004/p/12980014.html