6

重排的回文串

http://www.nowcoder.com/questionTerminal/a45ace35d2414b4081b229100d96d7aa

include

include

include

include

include

using namespace std;
typedef long long ll;

const int A = 1e5 + 10;
vector<int> v;
int siz,sum[A],n,m;
ll Ans[A],cnt[A],res;
char s[A];
class Que{
public:
int l,r,id;
bool operator<(const Que& rhs) const{
if(l/siz == rhs.l/siz) return r/siz < rhs.r/siz;
return l/siz < rhs.l/siz;
}
}Q[A];
class Gra{
public:
int v,next;
}G[A*50];
int head[A],tot;</int>

void update(int pos,int c){
if(c == -1) cnt[sum[pos]] += c;
res += ccnt[sum[pos]];
for(int i=head[sum[pos]] ;i!=-1 ;i=G[i].next){
res += c
cnt[G[i].v];
}
if(c == 1) cnt[sum[pos]] += c;
}

void add(int u,int v){
G[tot].v = v;
G[tot].next = head[u];
head[u] = tot++;
}

void solve(){
int L = 0,R = -1;res = 0;
for(int i=1 ;i<=m ;i++){
int id = Q[i].id;
while(R < Q[i].r) update(++R,1);
while(L > Q[i].l) update(--L,1);
while(R > Q[i].r) update(R--,-1);
while(L < Q[i].l) update(L++,-1);
Ans[id] = res;
}

}

int main(){
scanf("%d%d",&n,&m);
scanf("%s",s+1);

sum[0] = 0;v.push_back(0);
siz = sqrt(1.0*n);

for(int i=1 ;i<=n ;i++){
    sum[i] = sum[i-1]^(1<<(s[i]-'a'));
    v.push_back(sum[i]);
}

sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());

int len = v.size();
memset(head,-1,sizeof(head));tot = 0;
for(int i=0 ;i<len ;i++){
    for(int j=0 ;j<26 ;j++){
        int x = v[i]^(1<<j);
        int k = lower_bound(v.begin(),v.end(),x) - v.begin();
        if(k>=0 && k<v.size() && v[k] == x) add(i,k);
    }
}
for(int i=0 ;i<=n ;i++) sum[i] = lower_bound(v.begin(),v.end(),sum[i]) - v.begin();

for(int i=1 ;i<=m ;i++){
    scanf("%d%d",&Q[i].l,&Q[i].r);
    Q[i].id = i;Q[i].l--;
}
sort(Q+1,Q+1+m);

solve();
for(int i=1 ;i<=m ;i++){
    printf("%lld\n",Ans[i]);
}
return 0;

}

全部评论

相关推荐

点赞 评论 收藏
分享
09-29 17:44
已编辑
蔚来_测(准入职员工)
//鲨鱼辣椒:见不了了我实习了四个月上周再投筛选了一天就给我挂了
点赞 评论 收藏
分享
Pandaileee:校友加油我现在也只有一个保底太难了
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务