求助 全RE 玄关
查看原帖
求助 全RE 玄关
557800
luuia楼主2024/4/29 18:10
#include<bits/stdc++.h>
using namespace std;

int read()
{
    int s = 0,w = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-') w = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        s = (s << 1) + (s << 3) + (ch ^ 48);
        ch = getchar();
    }
    return s * w;
}

void write(int a)
{
    if(a < 0) putchar('-'),a = -a;
    if(a > 9) write(a / 10);
    putchar(a % 10 + '0');
}

const int N = 3e5 + 10,M = 6e7 + 10,p = 1e9 + 7;

int n,m,c,u,v,w,x,y,z;
int tmp[N],cnt;
int opt,l,r,l1,r1,l2,r2,k,ans;

struct FHQ
{

int tot,root;
int val[M],dat[M],size[M],son[M][2];
int sum[M],cov[M],ad[M];
bool lazy[M];

int New(int x)
{
    val[++tot] = sum[tot] = x;
    size[tot] = 1,dat[tot] = rand();
    son[tot][0] = son[tot][1] = 0;
    lazy[tot] = ad[tot] = 0;
    cov[tot] = -1;
    return tot;
}

int clone(int p)
{
    int q = ++tot;
    val[q] = val[p],dat[q] = dat[p];
    size[q] = size[p],sum[q] = sum[p];
    son[q][0] = son[p][0];
    son[q][1] = son[p][1];
    cov[q] = cov[p],ad[q] = ad[p];
    lazy[q] = lazy[p];
    return q;
}

void cover(int p,int c)
{
    val[p] = c,cov[p] = c % p,ad[p] = 0;
    sum[p] = (long long)size[p] * (long long)c % p;
}

void add(int p,int c)
{
    val[p] = ((long long)val[p] + c) % p;
    sum[p] = ((long long)sum[p] + ((long long)size[p] * (long long)c) % p) % p;
    ad[p] = (ad[p] + c) % p;
}

void pushup(int p)
{
    size[p] = size[son[p][0]] + size[son[p][1]] + 1;
    sum[p] = ((long long)sum[son[p][0]] + (long long)sum[son[p][1]] + (long long)val[p]) % p;
}

void pushdown(int p)
{
    if(cov[p] == -1 && lazy[p] == 0 && ad[p] == 0) return;
    if(son[p][0]) son[p][0] = clone(son[p][0]);
    if(son[p][1]) son[p][1] = clone(son[p][1]);
    if(lazy[p])
    {
        if(son[p][0]) lazy[son[p][0]] ^= 1;
        if(son[p][1]) lazy[son[p][1]] ^= 1;
        swap(son[p][0],son[p][1]);
        lazy[p] = 0;
    }
    if(cov[p] != -1)
    {
        if(son[p][0]) cover(son[p][0],cov[p]);
        if(son[p][1]) cover(son[p][1],cov[p]);
        cov[p] = -1;
    }
    if(ad[p])
    {
        if(son[p][0]) add(son[p][0],ad[p]);
        if(son[p][1]) add(son[p][1],ad[p]);
        ad[p] = 0;
    }
}

void split(int p,int k,int &x,int &y)
{
    if(p == 0) {x = y = 0;return;}pushdown(p);
    if(size[son[p][0]] + 1 <= k) 
    {
        x = clone(p);
        split(son[p][1],k - size[son[p][0]] - 1,son[x][1],y);
        pushup(x);
    }
    else 
    {
        y = clone(p);
        split(son[p][0],k,x,son[y][0]);
        pushup(y);
    }
}

int merge(int u,int v)
{
    if(u == 0 || v == 0) return u | v;
    if(dat[u] < dat[v])
    {
        u = clone(u);
        pushdown(u);
        son[u][1] = merge(son[u][1],v);
        pushup(u);
        return u;
    }
    else
    {
        v = clone(v);
        pushdown(v);
        son[v][0] = merge(u,son[v][0]);
        pushup(v);
        return v;
    }
}

int build(int l,int r)
{
    if(l > r) return 0;
    int mid = (l + r) >> 1;
    int k = New(tmp[mid]);
    son[k][0] = build(l,mid - 1);
    son[k][1] = build(mid + 1,r);
    pushup(k);return k;
}

void dfs(int p)
{
    pushdown(p);
    if(son[p][0]) dfs(son[p][0]);
    tmp[++cnt] = val[p];
    if(son[p][1]) dfs(son[p][1]);
}

int Query_sum(int l,int r)
{
    int x,y,z;
    split(root,r,x,z);
	split(x,l - 1,x,y);
    int t = sum[y];
    root = merge(merge(x,y),z);
    return t;
}

void Cover(int l,int r,int k)
{
    int x,y,z;
    split(root,r,x,z);
	split(x,l - 1,x,y);
    y = clone(y);
    cover(y,k);
    root = merge(merge(x,y),z);
}

void Add(int l,int r,int k)
{
    int x,y,z;
    split(root,r,x,z);
	split(x,l - 1,x,y);
    y = clone(y);
    add(y,k);
    root = merge(merge(x,y),z);
}

void Copy(int l1,int r1,int l2,int r2)
{
    int x,y,z,v,w;
    bool flag = 0;
	if(l1 > l2) swap(l1,l2),swap(r1,r2),flag = 1;
	split(root,r2,x,v);
	split(x,l2 - 1,x,w);
	split(x,r1,x,z);
	split(x,l1 - 1,x,y);
	if(flag) y = clone(w);
	else w = clone(y);
	root = merge(merge(merge(merge(x,y),z),w),v);
}

void Swap(int l1,int r1,int l2,int r2)
{
    int x,y,z,v,w;
    if(l1 > l2) swap(l1,l2),swap(r1,r2);
	split(root,r2,x,v);
	split(x,l2 - 1,x,w);
	split(x,r1,x,z);
	split(x,l1 - 1,x,y);
	y = clone(y),w = clone(w),swap(y,w);
	root = merge(merge(merge(merge(x,y),z),w),v);
}

void Reverse(int l,int r)
{
    int x,y,z;
    split(root,r,x,z);
	split(x,l - 1,x,y);
    y = clone(y);
    lazy[y] ^= 1;
    root = merge(merge(x,y),z);
}

void rebuild()
{
    cnt = 0,dfs(root);
    root = tot = 0;
    root = build(1,n);
}

void print(int p)
{
    cnt = 0,dfs(root);
    for(int i = 1;i <= n;i++) cout << tmp[i] << " ";
    cout << endl;
}

}tree;

int main()
{
    // freopen("input.in","r",stdin);
    // freopen("out.out","w",stdout);
    n = read(),m = read();
    for(int i = 1;i <= n;i++) tmp[i] = read();
    tree.root = tree.build(1,n);
    cnt = 0,tree.dfs(tree.root);
    // tree.print(tree.root);
    while(m--)
    {
        opt = read();
        if(opt == 1)
        {
            l = read(),r = read();
            l ^= ans,r ^= ans;
            ans = tree.Query_sum(l,r);
            write(ans),putchar('\n');
        }
        if(opt == 2)
        {
            l = read(),r = read(),k = read();
            l ^= ans,r ^= ans,k ^= ans;
            tree.Cover(l,r,k);
        }
        if(opt == 3)
        {
            l = read(),r = read(),k = read();
            l ^= ans,r ^= ans,k ^= ans;
            tree.Add(l,r,k);
        }
        if(opt == 4)
        {
            l1 = read(),r1 = read(),l2 = read(),r2 = read();
            l1 ^= ans,l2 ^= ans,r1 ^= ans,r2 ^= ans;
            tree.Copy(l1,r1,l2,r2);
        }
        if(opt == 5)
        {
            l1 = read(),r1 = read(),l2 = read(),r2 = read();
            l1 ^= ans,l2 ^= ans,r1 ^= ans,r2 ^= ans;
            tree.Swap(l1,r1,l2,r2);
        }
        if(opt == 6)
        {
            l = read(),r = read();
            l ^= ans,r ^= ans;
            tree.Reverse(l,r);
        }
        if(tree.tot + 400000 >= M) tree.rebuild();
        // tree.print(tree.root);
    }
    cnt = 0,tree.dfs(tree.root);
    for(int i = 1;i <= n;i++) cout << tmp[i] << " ";
    return 0;
}
2024/4/29 18:10
加载中...