广州市网站制作,电商专业学什么,国际军事新闻最新,手机网站开发开发正题
评测记录:https://www.luogu.org/recordnew/lists?uid52918pidP3501 大意
一个01串#xff0c;如果一个串翻转后取反和原串是相同的#xff0c;那么这就是个反对称的。求这个01串有多少个子串是反对称的。 解题思路
一个反对称串就是将这个串取反然后放在原串后…正题
评测记录:https://www.luogu.org/recordnew/lists?uid52918pidP3501 大意
一个01串如果一个串翻转后取反和原串是相同的那么这就是个反对称的。求这个01串有多少个子串是反对称的。 解题思路
一个反对称串就是将这个串取反然后放在原串后面的话是回文串然后回文串是满足单调性的如果以一个点为中心扩展k格是回文串那么扩展k-1格也是回文串所以我们可以枚举中心然后二分最大的k然后用hash判断回文。 code
#includecstdio
#includecstring
#includeiostream
#define ull unsigned long long
#define N 500010
const ull hashmath2000001001;
using namespace std;
int n;
ull wer[N],hash[N],rhash[N],ans;
char s[N];
bool check(int l,int r,int x)//判断回文
{ull s1,s2;int t1,t2;t1lx-1;t2rx-1;s1hash[t1]-hash[l-1];s2rhash[t2]-rhash[r-1];//前缀和if(lr) {swap(s1,s2);swap(l,r);}s1*wer[r-l];//减去差值return s1s2;
}
int main()
{scanf(%d\n,n);scanf(%s,s);wer[0]1;for (int i1;in;i) wer[i]wer[i-1]*hashmath;for (int i1;in;i)hash[i]hash[i-1]s[i-1]*wer[i];for (int i1;in/2;i) swap(s[i-1],s[n-i]);for (int i1;in;i)if (s[i-1]0) s[i-1]1;else s[i-1]0;//取反for (int i1;in;i)rhash[i]rhash[i-1]s[i-1]*wer[i];for(int i2;in;i){int jn-i2,l1,rmin(n-i1,n-j1);int maxs0;while(lr){int mid(lr)1;//二分if(check(i,j,mid))maxsmax(mid,maxs),lmid1;else rmid-1;}ansmaxs;//统计答案}printf(%lld,ans);
}