Codeforces Round #616 (Div. 2) D

莫队的模板

struct node{
    int l,r,id;
}q[maxn];
int cmp(node a,node b) {
    return (belong[a.l] ^ belong[b.l]) ? belong[a.l] < belong[b.l] : ((belong[a.l] & 1) ? a.r < b.r : a.r > b.r);
}

    n=strlen(s);
    size = sqrt(n);
    bnum = n / size;
    for(int i = 1; i <= bnum; ++i)
        for(int j = (i - 1) * size + 1; j <= i * size; ++j) {
            belong[j] = i;
    }
    int ql = q[i].l, qr = q[i].r;
        while(l < ql) now -= !--cnt[aa[l++]];
        while(l > ql) now += !cnt[aa[--l]]++;
        while(r < qr) now += !cnt[aa[++r]]++;
        while(r > qr) now -= !--cnt[aa[r--]];
        ans[q[i].id] = now;//now代表ql~qr之间有多少不同的数字

思路:

区间有多少种不同的字母,ql==qr yes ,三种以上yes,首尾不相等的yes其他都是no

莫队写法

二维树状数组写法

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define il inline
#define it register int
#define lowbit(x) (x)&(-x)
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 1000000007
const int maxn=2e5+10;
char s[maxn];
int cnt[maxn],belong[maxn],b[maxn],l=1,r=0,now=0,n,ql,qr,ls,ci;
struct node{
    int l,r,id,da;
}q[maxn];
int cmp(node a,node b) {
    return (belong[a.l] ^ belong[b.l]) ? belong[a.l] < belong[b.l] : ((belong[a.l] & 1) ? a.r < b.r : a.r > b.r);
}
int cmp1(node a,node b){
    return a.id<b.id;
}
il void add(int pos){
    if(!cnt[s[pos]-'a']){++now;}
    ++cnt[s[pos]-'a'];
}
il void del(int pos){
    --cnt[s[pos]-'a'];
    if(!cnt[s[pos]-'a'])--now;
}
il int work(int q,int p){
    while(l<q)del(l++);
    while(l>q)add(--l);
    while(r<p)add(++r);
    while(r>p)del(r--);
    return now;
}
int main(){
    scanf("%s",s+1);
    ls=strlen(s+1);
    ci=sqrt(ls);
    int ge=ls/ci;
    for(it i=1;i<=ge;i++){
        for(it j=(i-1)*ci+1;j<=i*ci;j++){
            belong[j]=i;
        }
    }
    scanf("%d",&n);
    for(it i=0;i<n;i++){
        scanf("%d%d",&q[i].l,&q[i].r);q[i].id=i;
    }
    sort(q,q+n,cmp);
    for(it i=0;i<n;i++){
        it ql=q[i].l,qr=q[i].r;
        it z=work(ql,qr);
        if(ql==qr){
            q[i].da=1;
        }
        else if(z>=3){
           q[i].da=1;
        }
        else if(s[ql]!=s[qr]){
            q[i].da=1;
        }
        else{
           q[i].da=-1;
        }
    }
    sort(q,q+n,cmp1);
    for(it i=0;i<n;i++){
        printf(q[i].da==1?"Yes
":"No
");
    }
    return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define il inline
#define it register int
#define lowbit(x) (x)&(-x)
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 1000000007
const int maxn=2e5+10;
char s[maxn];
struct node{
    int tr[maxn];
    void inint(){
        memset(tr,0,sizeof(tr));
    }
    void updata(int x,int y){
        for(int i=x; i<=maxn; i+=lowbit(i)){
            tr[i]+=y;
        }
    }
    int geshu(int x,int y){
        int sum1=0,sum2=0;
        for(int i=x; i>0; i-=lowbit(i)){
            sum1+=tr[i];
        }
        for(int i=y; i>0; i-=lowbit(i)){
            sum2+=tr[i];
        }
        return sum2-sum1;
    }
} a[27];
int main(){
    for(it i=0;i<26;i++){
        a[i].inint();
    }
    scanf("%s",s+1);
    int ls=strlen(s+1);
    for(it i=1;i<=ls;i++){
        a[s[i]-'a'].updata(i,1);
    }
    it n,l,r;
    scanf("%d",&n);
    for(it i=0;i<n;i++){
        scanf("%d%d",&l,&r);
        it z=0;
        if(l==r || s[l]!=s[r]){
            printf("Yes ");continue;
        }
        for(it i=0;i<26;i++){
            if(a[i].geshu(l,r)){
                z++;
            }
        }
        if(z>=3){
           printf("Yes ");
        }
        else{
           printf("No ");
        }
    }
    return 0;
}

这场打得有些自闭了

搞不懂c题,B题wa4发发现思路是错误的,最后在辉辉给出正确思路之后才过

D题就瞄了一眼,以为很难,赛后补题写了一个二维树状数组就过了,看了大佬的博客发现可以用莫队写,就试着用模板写

原文地址:https://www.cnblogs.com/luoyugongxi/p/12256090.html