您的位置:首页 > 其它

B 洛谷 P3604 美好的每一天 [莫队算法]

2017-02-02 15:24 337 查看

题目背景

时间限制3s,空间限制162MB

素晴らしき日々

我们的情人,不过是随便借个名字,用幻想吹出来的肥皂泡,把信拿去吧,你可以使假戏成真。我本来是无病呻吟,漫无目的的吐露爱情---现在这些漂泊不定的鸟儿有地方栖息了,你可以从信里看出来。拿去吧---由于不是出自真心,话就说得格外动听,拿去吧,就这么办吧...

由于世界会在7月20日完结,作为救世主,间宫卓司要在19日让所有人回归天空

现在已经是19日傍晚,大家集合在C栋的天台上,一共n个人

在他们面前,便是终之空,那终结的天空

题目描述

回归天空是一件庄重的事情,所以卓司决定让大家分批次进行,给每个人给了一个小写字母'a'->'z'作为编号

一个区间的人如果满足他们的编号重排之后可以成为一个回文串,则他们可以一起回归天空,即这个区间可以回归天空

由于卓司是一个喜欢妄想的人,他妄想了m个区间,每次他想知道每个区间中有多少个子区间可以回归天空

因为世界末日要来了,所以卓司的信徒很多

输入输出格式

输入格式:

第一行两个数n,m

之后一行一个长为n的字符串,代表每个人的编号

之后m行每行两个数l,r代表每次卓司妄想的区间

输出格式:

m行,每行一个数表示答案

输入输出样例

输入样例#1:

6 6
zzqzzq
1 6
2 4
3 4
2 3
4 5
1 1


输出样例#1:

16
4
2
2
3
1


说明

对于10%的数据,n,m<=100

对于30%的数据,n,m<=2000

对于100%的数据,n,m<=60000

字符集大小有梯度

在大家回归天空之后,彩名露出了阴冷的笑容

先奉上O(n2) 30分骗分

//
//  main.cpp
//  BB
//
//  Created by Candy on 2017/2/2.
//  Copyright © 2017年 Candy. All rights reserved.
//
#pragma GCC optimize("O2")

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=6e4+5,M=(1<<26)+5;
inline int read(){
char c=getchar();register int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
return x*f;
}
int n,Q,a
,bl,pos
,bit[27];
char s
;
struct ques{
int l,r,id;
bool operator <(const ques &a)const{
return pos[l]==pos[a.l]?r<a.r:pos[l]<pos[a.l];
}
}q
;
unsigned short c[M];
int ans,anss
;
inline void add(int x){//printf("add %d %d\n",x,a[x]);
ans+=c[a[x]]++;
for(register int i=0;i<26;i++) ans+=c[a[x]^bit[i]];
}
inline void del(int x){
ans-=--c[a[x]];
for(register int i=0;i<26;i++) ans-=c[a[x]^bit[i]];
}
inline void solve(){
for(int i=0;i<26;i++) bit[i]=1<<i;
sort(q+1,q+1+Q);
c[0]++;
int l=1,r=0;
for(int i=1;i<=Q;i++){//printf("Q %d %d %d\n",q[i].l,q[i].r,q[i].id);
while(r<q[i].r) add(++r);//printf("hi %d %d %d\n",l,r,ans);
while(r>q[i].r) del(r--);//printf("hi %d %d %d\n",l,r,ans);
while(l<q[i].l) del(l-1),l++;//printf("hi %d %d %d\n",l,r,ans);
while(l>q[i].l) add(--l-1);//printf("hi %d %d %d\n",l,r,ans);
anss[q[i].id]=ans;
}
for(int i=1;i<=Q;i++) printf("%d\n",anss[i]);
}
int main(int argc, const char * argv[]) {
n=read();Q=read();
scanf("%s",s+1);
bl=sqrt(n);
for(int i=1;i<=n;i++) a[i]=(1<<(s[i]-'a'))^a[i-1],pos[i]=(i-1)/bl+1;
for(int i=1;i<=Q;i++) q[i].l=read(),q[i].r=read(),q[i].id=i;
solve();
return 0;
}


卡常后很丑
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: