其他分享
首页 > 其他分享> > 【训练题42:可持久化权值线段树】Stone Games | 2020 ICPC昆明站 M题

【训练题42:可持久化权值线段树】Stone Games | 2020 ICPC昆明站 M题

作者:互联网

前置知识

题意

思路

代码

#include<bits/stdc++.h>
using namespace std;
void show(){std::cerr << endl;}template<typename T,typename... Args>void show(T x,Args... args){std::cerr << "[ " << x <<  " ] , ";show(args...);}

#define ll long long
#define ls tree[p].lson
#define rs tree[p].rson
#define md ((l+r)>>1)

const int MAX = 1e6+50;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const double EPS = 1e-5;

int aa[MAX];

struct SegmentTree{
    int lson,rson;
    ll sum;
}tree[MAX*40];
int root[MAX];

int idx;
void NewNode(){
    idx++;
    tree[idx].lson = tree[idx].rson = tree[idx].sum = 0;
}

void push_up(int p){
    tree[p].sum = tree[ls].sum + tree[rs].sum;
}

void Insert(int p,int l,int r,ll k){
    tree[p].sum += k;
    if(l == r)return;

    NewNode();
    if(k <= md){
        if(ls)tree[idx] = tree[ls];
        ls = idx;
        Insert(ls,l,md,k);
    }else{
        if(rs)tree[idx] = tree[rs];
        rs = idx;
        Insert(rs,md+1,r,k);
    }
    push_up(p);
}

ll query(int l,int r,const ll &qx,const ll &qy,int c1,int c2){		// 注意询问范围是 long long 的!
    if(tree[c2].sum - tree[c1].sum == 0)return 0;

    if(qx <= l && qy >= r){
        return tree[c2].sum - tree[c1].sum;
    }
    ll res = 0;
    if(md >= qx)res += query(l,md,qx,qy,tree[c1].lson,tree[c2].lson);
    if(md <  qy)res += query(md+1,r,qx,qy,tree[c1].rson,tree[c2].rson);
    return res;
}

const int YOU = 1000000000;
int n,m;
void init(){

    idx = 0;
    n = read();m = read();
    for(int i = 1;i <= n;++i){
        aa[i] = read();
    }

    NewNode();
    root[0] = idx;

    for(int i = 1;i <= n;++i){
        NewNode();
        root[i] = idx;
        tree[root[i]] = tree[root[i-1]];
        Insert(root[i],1,YOU,aa[i]);
    }

}

int main()
{
    init();

    ll lst = 0,you = 0;
    for(int i = 1;i <= m;++i){
        int l1,r1,l,r;
        l1 = read();r1 = read();
        l = min( (l1+you) % n + 1,(r1 + you) % n + 1);
        r = max( (l1+you) % n + 1,(r1 + you) % n + 1);

        lst = you = 0;

        while(1){
            ll sum = query(1,YOU,lst+1,you+1,root[l-1],root[r]);
//            show(l,r,lst+1,you+1,sum);
            if(sum == 0)break;
            lst = you + 1;
            you = you + sum;
        }
        you++;
        Print(you,'\n');
    }
    Write();


    return 0;
}

标签:Stone,idx,int,42,sum,tree,ICPC,root,ll
来源: https://blog.csdn.net/weixin_45775438/article/details/119043347