Title Description
Title, you need to perform the following two operations, known as a sequence:
1. Add x to each number in a range
2. Multiply each number in an interval by x
3. Find out the amount of each number in a range and
Input/output format
Input format:
The first line contains three integers n, M, P, respectively, indicating the number of numbers, the total number of operations and modulus.
The second line contains n space-delimited integers, where the I number represents the initial value of item I of a sequence.
The next M line contains 3 or 4 integers, representing an operation, as follows:
Action 1: Format: 1 x y k meaning: Multiply each number in the interval [x, y] by K
Action 2: Format: 2 x y k meaning: Add K to each number in the interval [x, y]
Action 3: Format: 3 x y meaning: The result of each number in the output interval [x, y] and P modulo
Output format:
The output contains several line integers, which is the result of all Operation 3.
Input and Output Sample input example # #:
5 5 381 5 4 2 32 1 4 13 2 51 2 4 22 3 5 53 1 4
Sample # # of output:
172
Description
Time limit: 1000ms,128m
Data size:
For 30% data: n<=8,m<=10
For 70% data: n<=1000,m<=10000
For 100% data: n<=100000,m<=100000
(data has been strengthened ^_^)
Sample Description:
Therefore the output should be 17, 2 (mod 38=2)
Ideas:
The main problem is not to break the first ride or add, I can be a stack of the same doctrine, the stack of line tree ... Forgive me for incompetence.
The general solution is to turn multiplication into addition.
(S+flag) *lazy=s*lazy+flag*lazy.
Attention:
Data size, not only to open a long long, but also to take the MoD regularly.
(According to the comments, it does not seem to be a long long, but even if the data is in the int range, because there is a multiplication operation, it is likely to be within a long long range.) Noip, the Linux format input and output LLD. )
Code implementation:
1#include <cstdio>2#include <iostream>3 using namespacestd;4 #defineLL Long Long5 LL n,m,mod,a,b,c,d;6 structNate{ll L,r,s,flag,lazy;} t[800000];//flag7 voidHeritage (LL k) {//Tag pass. 8 if(t[k].lazy==1&&t[k].flag==0)return;9 if(T[K].L==T[K].R) {t[k].flag=0; t[k].lazy=1;return;}TenLL lson=k*2, rson=k*2+1; OneT[lson].s= (T[lson].s*t[k].lazy)%mod+ (t[k].flag* (t[lson].r-t[lson].l+1))%mod)%MoD; AT[lson].flag= ((t[lson].flag*t[k].lazy)%mod+t[k].flag)%MoD; -t[lson].lazy= (t[lson].lazy*t[k].lazy)%MoD; -T[rson].s= (T[rson].s*t[k].lazy)%mod+ (t[k].flag* (t[rson].r-t[rson].l+1))%mod)%MoD; theT[rson].flag= ((t[rson].flag*t[k].lazy)%mod+t[k].flag)%MoD; -t[rson].lazy= (t[rson].lazy*t[k].lazy)%MoD; -t[k].flag=0; t[k].lazy=1; - } + voidMake_tree (LL k,ll l,ll R) {//achievements. General Building method. -LL lson=k*2, rson=k*2+1; +t[k].l=l;t[k].r=r;t[k].lazy=1; A if(L==R) {scanf ("%lld", &t[k].s); t[k].s%=mod;return;} atLL mid= (l+r)/2; - Make_tree (lson,l,mid); -Make_tree (rson,mid+1, R); -t[k].s= (T[LSON].S+T[RSON].S)%MoD; - } - voidInterval_add (LL k,ll l,ll r,ll v) {//Add more value. inLL lson=k*2, rson=k*2+1; - Heritage (k); to if(t[k].l==l&&t[k].r==R) { +t[k].flag=v; -T[k].s= (t[k].s+ (t[k].r-t[k].l+1) *v)%mod)%MoD; the return; * } $LL mid= (T[K].L+T[K].R)/2;Panax Notoginseng if(l<=mid) Interval_add (Lson,l,min (r,mid), v); - if(R>mid) Interval_add (Rson,max (l,mid+1), r,v); thet[k].s= (T[LSON].S+T[RSON].S)%MoD; + } A voidinterval_ride (LL k,ll l,ll r,ll v) {//Multiply more values. theLL lson=k*2, rson=k*2+1; + Heritage (k); - if(t[k].l==l&&t[k].r==R) { $t[k].lazy=v; $t[k].s= (t[k].s*v)%MoD; - return; - } theLL mid= (T[K].L+T[K].R)/2; - if(l<=mid) Interval_ride (Lson,l,min (r,mid), v);Wuyi if(R>mid) Interval_ride (Rson,max (l,mid+1), r,v); thet[k].s= (T[LSON].S+T[RSON].S)%MoD; - } Wu ll Interval_query (ll k,ll l,ll R) {//Interval query. - intlson=k*2, rson=k*2+1; About Heritage (k); $ if(T[K].L==L&&T[K].R==R)returnT[k].s; -LL mid= (T[K].L+T[K].R)/2, ans=0; - if(L<=mid) ans+=interval_query (Lson,l,min (R,mid)); - if(R>mid) Ans+=interval_query (Rson,max (l,mid+1), R); A returnans%MoD; + } the intMain () { -scanf"%lld%lld%lld",&n,&m,&MoD); $Make_tree (1,1, n); the for(intI=1; i<=m;i++){ thescanf"%lld",&a); the if(a==1){ thescanf"%lld%lld%lld",&b,&c,&d); -Interval_ride (1, b,c,d%MoD); in } the if(a==2){ thescanf"%lld%lld%lld",&b,&c,&d); AboutInterval_add (1, b,c,d%MoD); the } the if(a==3){ thescanf"%lld%lld",&b,&c); +printf"%lld\n", Interval_query (1, B,c)); - } the }Bayi return 0; the}
Do you feel sick and slow down?
Template Segment Tree 2