zoukankan      html  css  js  c++  java
  • 字符串+置换+莫队离线处理——cf1290B

    /*
    题意可以转化为通过s[l..r]构造出新的串t[l..r]和s不能约
        t[l..r]的每个前缀,每个后缀的字符数量都必须和s[l..r]对应的前后缀字符数量不同 
    构造策略:
        如果s[l]!=s[r]直接交换即可
        否则找到s[i]!=s[j],swap(s[i],s[r]),swap(s[j],s[l]),即此时只要s[l..r]有三种不同的字符即可 
    所以统计每个区间内出现的字符种数即可 
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define N 300005
    
    int block,n,q,ans[N];
    char s[N];
    struct Query{
        int l,r,id,tot;
    }Q[N];
    int cmp(Query a,Query b){
        if(a.l/block==b.l/block)return a.r<b.r;
        return a.l<b.l; 
    }
    
    int cnt[26],tot;
    void add(int x){
        cnt[s[x]-'a']++;
        if(cnt[s[x]-'a']==1)tot++;
    }
    void del(int x){
        cnt[s[x]-'a']--;
        if(cnt[s[x]-'a']==0)tot--;
    }
    
    int main(){
        scanf("%s",s+1);
        n=strlen(s+1);
        cin>>q;
        for(int i=1;i<=q;i++){
            cin>>Q[i].l>>Q[i].r;
            Q[i].id=i;
        }
        /*if(n>200){
            cout<<Q[14].l<<" "<<Q[14].r<<'
    ';
            for(int i=25336;i<=25341;i++)cout<<s[i];
            
        }*/
        block=sqrt(n);
        sort(Q+1,Q+1+q,cmp);
        
        int L=1,R=0;
        for(int i=1;i<=q;i++){
            while(R<Q[i].r)add(++R);
            while(L>Q[i].l)add(--L);
            while(R>Q[i].r)del(R--);
            while(L<Q[i].l)del(L++);
            Q[i].tot=tot;
        }
        
        for(int i=1;i<=q;i++){
            int l=Q[i].l,r=Q[i].r;
            if(s[l]!=s[r] || l==r)ans[Q[i].id]=1;
            else if(Q[i].tot>=3)ans[Q[i].id]=1;
        }
        
        for(int i=1;i<=q;i++)
            if(ans[i])puts("YES");
            else puts("NO");
    }
  • 相关阅读:
    10.28
    10.29
    11.05周四
    数据库增删改查
    11.03Tuesday
    11.10
    连接数据库
    10.30
    11.04周三
    10.27
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12270046.html
Copyright © 2011-2022 走看看