UESTC 电子科大专题训练 数据结构 C

UESTC 1597t

题意:中文题

思路:将每个点展开为 x*lazy1+lazy2, lazy1标记乘了多少 lazy2标记加了多少,每次区间乘的时候即 sum*c=(x*lazy1+lazy2)*c=x*lazy1*c+lazy2*c,区间加的时候为sum+c=(x*lazy1+lazy2)+c=x*lazy1+lazy2+c,每次对lazy标记的时候乘要同时对lazy1和lazy2进行标记

AC代码:

#include "iostream"
#include "string.h"
#include "stack"
#include "queue"
#include "string"
#include "vector"
#include "set"
#include "map"
#include "algorithm"
#include "stdio.h"
#include "math.h"
#define ll long long
#define bug(x) cout<<x<<" "<<"UUUUU"<<endl;
#define mem(a) memset(a,0,sizeof(a))
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define lrt (root*2)
#define rrt (root*2+1)
#define len (r-l+1)
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
const long long INF = 1e18+1LL;
const int inf = 1e9+1e8;
const int N=1e5+100;
const ll mod=1e9+7;

ll a[N<<2],lazy1[N<<2],lazy2[N<<2],n,m,p;
void push_up(int root){
    a[root]=(a[lrt]+a[rrt])%p;
}
void push_down(int root, int m){
    lazy1[lrt]=(lazy1[root]*lazy1[lrt])%p;
    lazy1[rrt]=(lazy1[root]*lazy1[rrt])%p;
    lazy2[lrt]=((lazy2[lrt]*lazy1[root])%p+lazy2[root])%p;
    lazy2[rrt]=((lazy2[rrt]*lazy1[root])%p+lazy2[root])%p;
    a[lrt]=((a[lrt]*lazy1[root])%p+(lazy2[root]*(m-(m>>1))%p))%p;
    a[rrt]=((a[rrt]*lazy1[root])%p+(lazy2[root]*(m>>1))%p)%p;
    lazy1[root]=1,lazy2[root]=0;
}
void creat(int root, int l, int r){
    if(l==r){
        scanf("%lld",&a[root]);
        a[root]%=p;
        return;
    }
    int mid=l+r>>1;
    creat(lrt, l, mid);
    creat(rrt, mid+1, r);
    push_up(root);
}
void updata1(int root, int l, int r, int L, int R, int c){
    if(l==L && r==R){
        lazy1[root]=(lazy1[root]*(c%p))%p;
        lazy2[root]=(lazy2[root]*(c%p))%p;
        a[root]=(a[root]*(c%p))%p;
        return;
    }
    if(lazy1[root]!=1 || lazy2[root]>0) push_down(root,len);
    int mid=l+r>>1;
    if(R<=mid)updata1(lrt, l, mid, L, R, c);
    else if(L>mid) updata1(rrt, mid+1, r, L, R, c);
    else updata1(lrt, l, mid, L, mid, c) , updata1(rrt, mid+1, r, mid+1, R, c);
    push_up(root);
}
void updata2(int root, int l, int r, int L, int R, int c){
    if(l==L && r==R){
        lazy2[root]=(((lazy2[root]+(c%p))%p))%p;
        a[root]=((a[root]+(c%p)*len)%p)%p;
        return;
    }
    if(lazy1[root]!=1 || lazy2[root]>0) push_down(root,len);
    int mid=l+r>>1;
    if(R<=mid) updata2(lrt, l, mid, L, R, c);
    else if(L>mid) updata2(rrt, mid+1, r, L, R, c);
    else updata2(lrt, l, mid, L, mid, c) , updata2(rrt, mid+1, r, mid+1, R, c);
    push_up(root);
}
ll query(int root, int l, int r, int L, int R){
    if(l==L && r==R){
        return a[root]%p;
    }
    if(lazy1[root]!=1 || lazy2[root]>0) push_down(root,len);
    int mid=l+r>>1;
    if(R<=mid) return query(lrt, l, mid, L, R)%p;
    else if(L>mid) return query(rrt, mid+1, r, L, R)%p;
    else return (query(lrt, l, mid, L, mid)+query(rrt, mid+1, r, mid+1, R))%p;
}
int main(){
    ///ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    cin>>n>>p;
    for(int i=0; i<=4*n; ++i) lazy1[i]=1;
    creat(1,1,n);
    cin>>m;
    int t,c,l,r;
    for(int i=1; i<=m; ++i){
        scanf("%d%d%d",&t,&l,&r);
        if(t==1){
            scanf("%d",&c);
            updata1(1,1,n,l,r,c);
        }
        else if(t==2){
            scanf("%d",&c);
            updata2(1,1,n,l,r,c);
        }
        if(t==3) printf("%lld\n",(query(1,1,n,l,r)+p)%p);
    }
    return 0;
}
时间: 2024-10-19 19:01:29

UESTC 电子科大专题训练 数据结构 C的相关文章

UESTC 电子科大专题训练 数据结构 D

UESTC 1584 题意:平面坐标上有n个怪物,每个怪物有一个rank值,代表x坐标和y坐标都不大于它本身的怪物数(不包括本身) 思路:对x y坐标从小到大排序,x优先排序,用数状数组计算y坐标小于它的数量 AC代码: #include "iostream" #include "string.h" #include "stack" #include "queue" #include "string" #i

UESTC 电子科大专题训练 数据结构 A

UESTC 1591 题意:求区间极值之差 思路:线段树裸题,不带更新 ACA代码: #include "iostream" #include "string.h" #include "stack" #include "queue" #include "string" #include "vector" #include "set" #include "ma

UESTC 电子科大专题训练 数据结构 J

UESTC 1599 题意:中文题..不写了 思路:优先对列,小的优先 AC代码: #include "iostream" #include "string.h" #include "stack" #include "queue" #include "string" #include "vector" #include "set" #include "map

UESTC 电子科大专题训练 数据结构 N

UESTC 1586 题意:中文题 思路:拆点并查集裸题 AC代码: #include "iostream" #include "string.h" #include "stack" #include "queue" #include "string" #include "vector" #include "set" #include "map"

UESTC 电子科大专题训练 数据结构 L

UESTC 1594 题意:中文题 思路:和poj食物链的题几乎一样,拆点或者带权并查集做,这种分类不多的比较倾向与拆点做 AC代码: #include "iostream" #include "string.h" #include "stack" #include "queue" #include "string" #include "vector" #include "se

UESTC 电子科大专题训练 数据结构-E

UESTC 1583 题意:中文题 思路:预处理将要变成的序列映射成1 2 3...n,数状数组每次求每个数前比它本身大的数,因为最后要变成1 2 3 ....n的序列,所以每个数字(映射后的)应该要交换到它值的位置上(也就是1的位置是1,2的位置是2,n的位置是n),如果当前数字(映射后的)前面有比它大的数,那必然要通过交换,将比他大的数交换到它后面去 AC代码: #include "iostream" #include "string.h" #include &

UESTC 电子科大专题训练 数论 L

UESTC 1723 题意:中文题 思路:预处理,dp[i][j]表示将j个人放到i个房间里,则可以得到dp[i][j]=dp[i][j-1]*i + dp[i-1][j-1],递推式的理解,第一:当有i个房间,j-1个人的时候方案数已知为dp[i][j-1],则当增加一个人的时候,第j个人可以选择i个房间的任意一个,或者选择一个新的房间,但是只有选择已有的i个房间才能递推得dp[i][j],第二:当有i-1个房间,j-1个人时,增加一个人,这个人有i+1种选择(i种选择为选择已有的房间,第i+

UESTC 电子科大专题训练 数论 G

UESTC 1718 题意:在01串中选出长度为偶数,并且前一半是0,后一半是1的子序列方案数 思路:组合数+范德蒙恒等式 记录每个数前面0的个数pi和后面1的个数nexi(包括本身)遍历到第k个数的时候,如果是0 那么方案数为(因为计算第i位时,前面计算的i-1个答案都不包含这一位,但是第i位计算的答案都包含第i位 所以没有重复) for(i=0, -> i=min(pi-1,nexi)) C(pi-1,i)*C(nexi,i+1) 可以由 C(l-1,i)=C(l,i+1)-C(l-1,i+

UESTC 电子科大专题训练 DP-F

UESTC 1271 题意:有一个n*m的地图,每个格子有一定数量的金子,如果是负数,说明是陷阱,将会失去金子,如果金子数小于0就会死掉,你可以往四个方向走,分别是:(x+1,y),(x,y+1),(x+1,y+2)(x+1,y),(x,y+1),(x+1,y+2)and(x+2,y+1) 问最多可以获得多少金子 思路:每一个格子最多可以通过4个方向到达,可推得递推式为 dp[i][j]=max(dp[i-1][j],dp[i][j-1],dp[i-1][j-2],dp[i-2][j-2])+g