珂朵莉树练习

 

 

 

CF896C Willem, Chtholly and Seniorious万恶之源

稍微有些复杂,因为操作比较多

  • 1 l r x :将[l,r]区间所有数加上x
  • 2 l r x :将[l,r] 区间所有数改成x
  • 3 l r x :输出将[l,r]区间从小到大排序后的第xx 个数是的多少(即区间第x 小,数字大小相同算多次,保证 1\leq x \leq r-l+1)
  • 4 l r x y :输出[l,r]区间每个数字的x次方的和模y的值(即((\sum^r_{i=l}a_i^x)\mod y )

 

/*author:revolIA*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 1e5+7,mod = 1e9+7;
struct node{
    int l,r;
    mutable ll val;
    bool operator < (const node o)const{
        return l<o.l;
    }
};
int n,q,ans,opt,l,r,x,y;
ll seed,Qmod;
ll random(){
    ll ret = seed;
    seed = (seed*7LL+13)%mod;
    return ret;
}
set<node> Tree;
typedef set<node>::iterator It;
It split(int pos){
    It it = Tree.lower_bound({pos,pos,0});
    if(it != Tree.end() && it->l == pos)return it;
    --it;
    int L = it->l,R = it->r;
    ll val = it->val;
    Tree.erase(it),Tree.insert({L,pos-1,val});
    return Tree.insert({pos,R,val}).first;
}
void Assign(int l,int r,int val){
    It itr = split(r+1),itl = split(l);
    Tree.erase(itl,itr),Tree.insert({l,r,1LL*val});
}
void Add(int l,int r,int val){
    It itr = split(r+1),itl = split(l);
    for(It i = itl;i!=itr;i++)
        i->val += val;
}
void out_k(int l,int r,int k){
    It itr = split(r+1),itl = split(l);
    vector<pair<ll,int> > vec;
    for(It i = itl;i!=itr;i++){
        vec.push_back({i->val,i->r-i->l+1});
    }
    sort(vec.begin(),vec.end());
    for(int i=0;i<vec.size();i++){
        k -= vec[i].second;
        if(k<=0){
            printf("%lld\n",vec[i].first);
            break;
        }
    }
}
int Pow(ll a,int b,int mod,int ans = 1){
    for(a%=mod;b;b>>=1,a=1LL*a*a%mod)if(b&1)
        ans = 1LL*ans*a%mod;
    return ans;
}
void Sum(int l,int r,int x,int y){
    It itr = split(r+1),itl = split(l);
    int sum = 0;
    for(It i=itl;i!=itr;i++){
        sum = (sum+1LL*(i->r-i->l+1)*Pow(i->val,x,y)%y)%y;
    }
    printf("%d\n",sum);
}
int main(){
    scanf("%d%d%lld%lld",&n,&q,&seed,&Qmod);
    for(int i=1;i<=n;i++){
        x = random()%Qmod+1;
        Tree.insert({i,i,x});
    }
    while(q--){
        opt = random()%4+1;
        l = random()%n+1;
        r = random()%n+1;
        if(l>r)swap(l,r);
        if(opt == 1){
            x = random()%Qmod+1;
            Add(l,r,x);
        }else if(opt == 2){
            x = random()%Qmod+1;
            Assign(l,r,x);
        }else if(opt == 3){
            x = random()%(r-l+1)+1;
            out_k(l,r,x);
        }else{
            x = random()%Qmod+1;
            y = random()%Qmod+1;
            Sum(l,r,x,y);
        }
    }
    return 0;
}

 

CF915E

 

区间置1,区间置0,询问总的1的个数

/*author:revolIA*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 1e5+7,mod = 1e9+7;
struct node{
    int l,r;
    mutable int val;
    bool operator < (const node o)const{
        return l<o.l;
    }
};
int n,q,ans,opt,l,r;
set<node> Tree;
typedef set<node>::iterator It;
It split(int pos){
    It it = Tree.lower_bound({pos,pos,0});
    if(it != Tree.end() && it->l == pos)return it;
    --it;
    int L = it->l,R = it->r,val = it->val;
    Tree.erase(it),Tree.insert({L,pos-1,val});
    return Tree.insert({pos,R,val}).first;
}
void Assign(int L,int R,int val){
    It itr = split(R+1),itl = split(L);
    for(It i=itl;i != itr;i++)
        ans -= i->val*(i->r-i->l+1);
    ans += (R-L+1)*val;
    Tree.erase(itl,itr),Tree.insert({L,R,val});
}
int main(){
    scanf("%d%d",&n,&q);
    ans = n;
    Tree.insert({1,n,1});
    while(q--){
        scanf("%d%d%d",&l,&r,&opt);
        Assign(l,r,opt-1);
        printf("%d\n",ans);
    }
    return 0;
}

 

 

 

P2572 [SCOI2010]序列操作

跑得快,代码短,还好调bug

 

 

/*author:revolIA*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 1e5+7,mod = 1e9+7;
struct node{
    int l,r;
    mutable bool val;
    bool operator < (const node o)const{
        return l<o.l;
    }
};
int n,q,ans,opt,l,r,x,y;
set<node> Tree;
typedef set<node>::iterator It;
It split(int pos){
    It it = Tree.lower_bound({pos,pos,0});
    if(it != Tree.end() && it->l == pos)return it;
    --it;
    int L = it->l,R = it->r;
    bool val = it->val;
    Tree.erase(it),Tree.insert({L,pos-1,val});
    return Tree.insert({pos,R,val}).first;
}
void Assign(int l,int r,bool val){
    It itr = split(r+1),itl = split(l);
    Tree.erase(itl,itr),Tree.insert({l,r,val});
}
void rever(int l,int r){
    It itr = split(r+1),itl = split(l);
    for(It i=itl;i!=itr;i++){
        i->val ^= 1;
    }
}
void Count1(int l,int r,int ans = 0){
    It itr = split(r+1),itl = split(l);
    for(It i=itl;i!=itr;i++)
        ans += i->val*(i->r-i->l+1);
    printf("%d\n",ans);
}
void Series(int l,int r){
    int ans = 0,tmp = 0;
    It itr = split(r+1),itl = split(l);
    for(It i=itl;i!=itr;i++){
        if(i->val){
            tmp += i->r-i->l+1;
        }else{
            ans = max(ans,tmp);
            tmp = 0;
        }
    }
    printf("%d\n",max(ans,tmp));
}
int main(){
    scanf("%d%d",&n,&q);
    for(int i=0,x;i<n;i++){
        scanf("%d",&x);
        Tree.insert({i,i,x});
    }
    while(q--){
        scanf("%d%d%d",&opt,&l,&r);
        if(opt == 0){
            Assign(l,r,0);
        }else if(opt == 1){
            Assign(l,r,1);
        }else if(opt == 2){
            rever(l,r);
        }else if(opt == 3){
            Count1(l,r);
        }else{
            Series(l,r);
        }
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值