• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
magicat
博客园    首页    新随笔    联系   管理    订阅  订阅
TorCoder

TorCoder

26棵线段树

  1. 建树,对于每个字符在响应字母的位置上进行修改数量
  2. 对于\([l,r]\)的重排,对26个字母进行区间查询出现的数量,判断是否可以组成,如果可以组成,将\([l,r]\)出现过字母的区间[l,r]赋值为0,然后根据字典序顺序对进行区间赋值操作
  3. \(m\)次操作后,对每个位置查询是哪个字母然后输出即可

细节见代码

// LUOGU_RID: 105747850
//  AC one more times
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define endl '\n'
#define all(x) (x).begin(), (x).end()
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<long long,long long> PLL;
const int mod = 1e9+7;
const int N = 1e5+10;


struct  segtree
{
    int s[N*4],sz[N*4],tag[N*4];
    void update(int id)
    {
        s[id]=s[id*2]+s[id*2+1];
        sz[id]=sz[id*2]+sz[id*2+1];
    }
    
    void settag(int id,int t)
    {
        tag[id]=t;
        if(t==0)
            s[id]=0;
        else if(t==1) 
            s[id]=sz[id];
    }

    void pushdown(int id)
    {
        if(tag[id]!=-1)
            settag(id*2,tag[id]),
            settag(id*2+1,tag[id]);
        tag[id]=-1;
    }

    void build(int id,int l,int r)
    {
        sz[id]=r-l+1;
        if(l==r)
        {
            s[id]=0;
            return;
        }
        int mid=(l+r)>>1;
        build(id*2,l,mid);
        build(id*2+1,mid+1,r);
        update(id);
    }

    void modify(int id,int l,int r,int ql,int qr,int t)
    {
        if(ql==l&&qr==r)
        {
            settag(id,t);           
            return;
        }
        pushdown(id);
        int mid=(l+r)>>1;
        if(qr<=mid)
            modify(id*2,l,mid,ql,qr,t);
        else if(ql>mid)
            modify(id*2+1,mid+1,r,ql,qr,t);
        else 
            modify(id*2,l,mid,ql,mid,t),
            modify(id*2+1,mid+1,r,mid+1,qr,t);
        update(id);
    }

    int query(int id,int l,int r,int ql,int qr)
    {
        //cout<<l<<" "<<r<<" "<<ql<<" "<<qr<<endl;
        if(ql==l&&r==qr)
        {
            return s[id];
        }
        pushdown(id);
        int mid=(l+r)>>1;
        if(qr<=mid)
            return query(id*2,l,mid,ql,qr);
        else if(ql>mid)
            return query(id*2+1,mid+1,r,ql,qr);
        else 
            return query(id*2,l,mid,ql,mid)+
                    query(id*2+1,mid+1,r,mid+1,qr);        
    }

}seg[27];
int op[27];
void solve()
{   
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    int n,q;
    cin>>n>>q;
    for(int i=1;i<=26;i++)
        seg[i].build(1,1,n);
    for(int i=1;i<=n;i++)
    {
        char c; cin>>c;
        seg[c-'a'+1].modify(1,1,n,i,i,1);
    }
   // cout<<"-----------------\n"<<endl;
    // for(int i=1;i<=n;i++)
    // {
    //     cout<<"i  : "<<i<<endl;
    //     for(int j=1;j<=26;j++)
    //     {
    //         cout<<char('a'+j-1)<<"   :  "<<seg[j].query(1,1,n,i,i)<<endl;
    //     }
    // }

    while(q--)
    {   
        int l,r;    cin>>l>>r;
        memset(op,0,sizeof op);
        for(int i=1;i<=26;i++)
            op[i]=seg[i].query(1,1,n,l,r);
        int ji=0,flag=0;
        for(int i=1;i<=26;i++)
            if(op[i]%2==1)
                ji++,flag=i;
        if(ji>=2)   continue;
        for(int i=1;i<=26;i++)
            seg[i].modify(1,1,n,l,r,0);
        int m=(l+r)>>1;
        if(ji!=0)
            seg[flag].modify(1,1,n,m,m,1),
            op[flag]--;
        int st=l,ed=r;
        for(int i=1;i<=26;i++)
        {
            if(op[i]==0)    continue;
            int cnt=op[i]/2;
            seg[i].modify(1,1,n,st,st+cnt-1,1);
            seg[i].modify(1,1,n,ed-cnt+1,ed,1);
            st+=cnt,ed-=cnt;
        }
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=26;j++)
            if(seg[j].query(1,1,n,i,i)==1)
                cout<<char('a'-1+j);
    cout<<endl;
     
}

  
int main()
{
    std::ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
  
    int TC = 1;
    
    //cin >> TC;    
    for(int tc = 1; tc <= TC; tc++)
    {
        //cout << "Case #" << tc << ": ";         
        solve();
    }


    return 0;
}

本文来自博客园,作者:magicat,转载请注明原文链接:https://www.cnblogs.com/magicat/p/17282595.html

posted on 2023-04-03 11:24  magicat  阅读(56)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3