Find Q
Accepts: 392
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 262144/131072 K (Java/Others)
问题描述
Byteasar迷恋上了'q'这个字母。
在他眼前有一个小写字母组成的字符串SSS,他想找出SSS的所有仅包含字母'q'的连续子串。但是这个字符串实在是太长了,你能写个程序帮助他吗?
输入描述
输入的第一行包含一个正整数T(1≤T≤10)T(1leq Tleq10)T(1≤T≤10),表示测试数据的组数。
对于每组数据,包含一行一个小写字母组成字符串SSS,保证SSS的长度不超过100000100000100000。
输出描述
对于每组数据,输出一行一个整数,即仅包含字母'q'的连续子串的个数。
输入样例
2 qoder quailtyqqq
输出样例
1 7
题解:尺取法直接上就好了,要注意数据范围 long long
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <bits/stdc++.h> using namespace std; typedef long long LL; const int N = 100005; char str[N]; int main() { freopen("a.txt","r",stdin); int tcase; scanf("%d",&tcase); while(tcase--){ scanf("%s",str+1); int len = strlen(str+1); LL l = 1,r = 1; long long cnt = 0; while(l<=len){ while(l<=len&&str[l]!='q') l++; r = l; while(r<=len&&str[r]=='q'){ r++; } if(r>l){ cnt+=(r-l)*(r-l+1)/2; } l = r; } printf("%lld ",cnt); } return 0; }
Abelian Period
Accepts: 288
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 262144/131072 K (Java/Others)
问题描述
设SSS是一个数字串,定义函数occ(S,x)occ(S,x)occ(S,x)表示SSS中数字xxx的出现次数。
例如:S=(1,2,2,1,3),occ(S,1)=2,occ(S,2)=2,occ(S,3)=1S=(1,2,2,1,3),occ(S,1)=2,occ(S,2)=2,occ(S,3)=1S=(1,2,2,1,3),occ(S,1)=2,occ(S,2)=2,occ(S,3)=1。
如果对于任意的iii,都有occ(u,i)=occ(w,i)occ(u,i)=occ(w,i)occ(u,i)=occ(w,i),那么我们认为数字串uuu和www匹配。
例如:(1,2,2,1,3)≈(1,3,2,1,2)(1,2,2,1,3)approx(1,3,2,1,2)(1,2,2,1,3)≈(1,3,2,1,2)。
对于一个数字串SSS和一个正整数kkk,如果SSS可以分成若干个长度为kkk的连续子串,且这些子串两两匹配,那么我们称kkk是串SSS的一个完全阿贝尔周期。
给定一个数字串SSS,请找出它所有的完全阿贝尔周期。
输入描述
输入的第一行包含一个正整数T(1≤T≤10)T(1leq Tleq10)T(1≤T≤10),表示测试数据的组数。
对于每组数据,第一行包含一个正整数n(n≤100000)n(nleq 100000)n(n≤100000),表示数字串的长度。
第二行包含nnn个正整数S1,S2,S3,...,Sn(1≤Si≤n)S_1,S_2,S_3,...,S_n(1leq S_ileq n)S1,S2,S3,...,Sn(1≤Si≤n),表示这个数字串。
输出描述
对于每组数据,输出一行若干个整数,从小到大输出所有合法的kkk。
输入样例
2 6 5 4 4 4 5 4 8 6 5 6 5 6 5 5 6
输出样例
3 6 2 4 8
题解:保存异或前缀异或和 ,k一定是 n的因子,所以枚举的 k不会很多.然后每隔k个比一下当前的异或和和前面异或和的异或值是否为0的就行了.
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <bits/stdc++.h> using namespace std; typedef long long LL; const int N = 100005; LL a[N],sum[N]; int factor[N],ans[N]; int main() { int tcase; scanf("%d",&tcase); while(tcase--) { int n; scanf("%d",&n); memset(sum,0,sizeof(sum)); for(int i=1; i<=n; i++) { scanf("%I64d",&a[i]); sum[i] = sum[i-1]^a[i]; } int id = 0,m = n; factor[id++] = 1; for(int i=2; i*i<=n; i++) { if(n%i==0) { if(i*i==n) factor[id++] = i; else { factor[id++] = n/i; factor[id++] = i; } } } factor[id++] = n; sort(factor,factor+id); int cnt = 0; bool flag = false; for(int j=0; j<id; j++) { bool flag = false; int k = factor[j]; for(int i=2*k; i<=n; i+=k) { LL pre = sum[i]^sum[i-k],nxt; if(i>=2*k) nxt = sum[i-k]^sum[i-2*k]; else nxt = sum[i-k]; if((pre^nxt)!=0) { flag = true; break; } } if(!flag) ans[cnt++] = k; } flag = true; for(int i=0;i<cnt;i++){ if(!flag) printf(" %d",ans[i]); else printf("%d",ans[i]); flag = false; } printf(" "); } return 0; }