[TJOI2018]数学计算
题目:[TJOI2018]数学计算
小数不能取模
树状数组的tr[p]表示包含a[p](位置p上的元素)的属性和(可能是和、乘..)
树状数组的性质:查前改后
线段树的形:边改边查
区间修改要有懒标记,若每个区间单点修改,它很慢
单点修改可以直接修改 O(lgn),不用懒标记
懒标记就是为区间修改而设计的,表示其子区间的待操作数
线段树就是要考虑维护什么东西
懒标记存什么样的操作数
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int const N=1e5+7;
ll tr[N<<2];
int t,m,mod;
void bulid(int p,int l,int r){
if(l==r){
tr[p]=1;return ;
}
int mid=(l+r) >> 1;
bulid(p*2,l,mid);
bulid(p*2+1,mid+1,r);
tr[p]=tr[p*2]*tr[p*2+1];
}
void add(int p,int l,int r,int pos,int w){
if(l==r){
if(l==pos) tr[p]=w;
tr[p]%=mod;
return ;
}
int mid=(l+r) >> 1;
if(pos<=mid) add(p*2,l,mid,pos,w);
if(mid+1<=pos) add(p*2+1,mid+1,r,pos,w);
tr[p]=tr[p*2]*tr[p*2+1];
tr[p]%=mod;
}
ll ask(int p,int l,int r,int x,int y){
if(x<=l&&r<=y) return tr[p];
int mid=(l+r) >> 1;
ll res=1;
if(x<=mid) res*=ask(p*2,l,mid,x,y);
if(mid+1<=y) res*=ask(p*2+1,mid+1,r,x,y);
return res;
}
int main(){
cin >> t;
while(t--){
cin >> m >> mod;
bulid(1,1,m);
int op,x;
for(int i=1;i<=m;++i){
cin >> op >> x;
if(op==1){
add(1,1,m,i,x);
//cout << ask(1,1,m,1,i)%mod << "\n";
cout << tr[1] << "\n";
}
else {
add(1,1,m,x,1);
//cout << ask(1,1,m,1,i)%mod << "\n";
cout << tr[1] << "\n";
}
}
}
return 0;
} 线段树和数状数组经典例题 文章被收录于专栏
线段树和数状数组经典例题
科大讯飞公司氛围 471人发布