题目描述
给你 𝑛n 个盒子,有 𝑞q 个操作,操作有两种:
- 第一种操作输入格式为
1 L R A B
,表示将编号为 𝐿L 到 𝑅R 的盒子里的石头数量变为 (𝑋−𝐿+1)×𝐴 mod 𝐵(X−L+1)×AmodB,其中 𝑋X 为盒子的编号。 - 第二种操作输入格式为
2 L R
,表示查询编号为 𝐿L 到 𝑅R 的盒子里的石头总数。
输入格式
第一行有两个数字 𝑛n(1≤𝑛≤1091≤n≤109),𝑞q (1≤𝑞≤5×1041≤q≤5×104)。
接下来 𝑞q 行表示询问操作。
输出格式
对于每个第二种操作,输出石头总数。
输入输出样例
输入 #1
6 3 2 1 6 1 1 5 1 2 2 1 6
输出 #1
0 3
输入 #2
4 5 1 1 4 3 4 2 1 1 2 2 2 2 3 3 2 4 4
输出 #2
3 2 1 0
输入 #3
4 4 1 1 4 7 9 2 1 4 1 1 4 1 1 2 1 4
输出 #3
16 0
说明/提示
- 对于 30%30% 的数据,𝑛,𝑞≤103n,q≤103;
- 对于 70%70% 的数据,𝑞≤103q≤103。
-
Code:
/*Code by 520 -- 9.7*/ #include<bits/stdc++.h> #define il inline #define ll long long #define RE register #define For(i,a,b) for(RE int (i)=(a);(i)<=(b);++(i)) #define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);--(i)) #define lson l,m,rt<<1 #define rson m,r,rt<<1|1 using namespace std; const int N=1000005; int n,m,flag[N],L[N],R[N],*Q[N],cnt,tot,val[N]; ll A[N],B[N]; struct node{ ll sum,a,b,st,len; }t[N]; int gi(){ int a=0;char x=getchar(); while(x<'0'||x>'9')x=getchar(); while(x>='0'&&x<='9')a=(a<<3)+(a<<1)+(x^48),x=getchar(); return a; } il bool cmp(int *a,int *b){return *a<*b;} ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} ll calc(ll a,ll b,ll n){ ll x=a/b;a%=b; ll sum=n*(n+1)/2*x; if(!a||!b) return sum; ll lala=n/b,m=a*n/b; return sum+n*m-calc(b,a,m)+lala; } il ll solve(ll a,ll b,ll n){ if(n<1)return 0; ll g=gcd(a,b); return n*(n+1)/2*a-b*calc(a/g,b/g,n); } il void pushup(int rt){t[rt].sum=t[rt<<1].sum+t[rt<<1|1].sum;} il void gai(ll A,ll B,ll st,int rt){ t[rt].a=A,t[rt].b=B,t[rt].st=st; t[rt].sum=solve(A,B,st+t[rt].len-1)-solve(A,B,st-1); } il void pushdown(int rt){ if(t[rt].b){ gai(t[rt].a,t[rt].b,t[rt].st,rt<<1); gai(t[rt].a,t[rt].b,t[rt].st+t[rt<<1].len,rt<<1|1); t[rt].b=0; } } void build(int l,int r,int rt){ if(l+1==r){t[rt]=node{0,0,0,0,val[r]-val[l]};return;} int m=l+r>>1; t[rt]=node{0,0,0,0,val[r]-val[l]}; build(lson),build(rson); } void update(ll A,ll B,int L,int R,int l,int r,int rt){ if(R<=l||r<=L)return; if(L<=l&&R>=r){gai(A,B,val[l]-val[L]+1,rt);return;} pushdown(rt); int m=l+r>>1; if(L<=m) update(A,B,L,R,lson); if(R>=m) update(A,B,L,R,rson); pushup(rt); } ll query(int L,int R,int l,int r,int rt){ if(R<=l||r<=L)return 0; if(L<=l&&R>=r)return t[rt].sum; pushdown(rt); int m=l+r>>1; ll ret=0; if(L<=m) ret+=query(L,R,lson); if(R>=m) ret+=query(L,R,rson); return ret; } int main(){ n=gi(),m=gi(); For(i,1,m) { flag[i]=gi(),L[i]=gi()-1,R[i]=gi(),Q[++tot]=&L[i],Q[++tot]=&R[i]; if(flag[i]==1) A[i]=gi(),B[i]=gi(); } sort(Q+1,Q+tot+1,cmp); int lst=-1; For(i,1,tot) if(*Q[i]!=lst) lst=*Q[i],*Q[i]=++cnt,val[cnt]=lst;else *Q[i]=cnt; build(1,cnt,1); For(i,1,m) if(flag[i]==1) update(A[i],B[i],L[i],R[i],1,cnt,1); else printf("%lld\n",query(L[i],R[i],1,cnt,1)); return 0; }