hdu5908
划分子序列为等长子串,这些子串要求两两匹配,匹配的含义是各个数字出现的次数一样。10w规模。
显然剪枝的方法就是利用子长度为总长的约数。匹配其实所有都和第一个子序列去匹配就好了。先++统计第一个,其余的
遇到一次--,全部是0就匹配成功。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<string> 6 #include<cmath> 7 #include<set> 8 #include<map> 9 #include<stack> 10 #include<queue> 11 #include<algorithm> 12 #include<sstream> 13 using namespace std; 14 #define ll long long 15 #define LL long long 16 #define inf 0x3f3f3f3f 17 #define llinf 0x3f3f3f3f3f3f3f3f 18 #define FOR(i,a,b) for(int i=a;i<=b;i++) 19 #define FORD(i,a,b) for(int i=b;i>=a;i--) 20 #define fp freopen("/Volumes/未命名2/Downloads/acm/in.txt","r",stdin) 21 #define ptarr(a,x,y) for(int _=x;_<=y;_++) if(_!=y) cout<<a[_]<<" ";else cout<<a[_]<<endl; 22 #define pt1(a) cout<<a<<endl; 23 #define pt2(a,b) cout<<a<<" "<<b<<endl; 24 #define pt3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl; 25 #define pt4(a,b,c,d) cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl; 26 #define ln1 cout<<"----------------------"<<endl; 27 #define ln2 cout<<"~~~~~~~~~~~~~~~~~~~~~~"<<endl; 28 #define CLR(a,b) memset(a,b,sizeof(a)); 29 struct node{ 30 int a, b; 31 bool operator<(const node& rhs)const { 32 if(a==rhs.a) 33 return b<rhs.b; 34 else return a<rhs.a; 35 } 36 }; 37 int T,n,m,K; 38 #define maxn 200000 39 int a[maxn],cnt[maxn]; 40 void read(){ 41 cin>>n; 42 FOR(i,1,n) cin>>a[i]; 43 } 44 void solve(){ 45 vector<int>ans; 46 FOR(len,1,n) 47 { 48 if(n%len!=0) continue; 49 else 50 { 51 int l=1,r=len,flg=1; 52 for(l=1,r=len;r<=n;l+=len,r+=len) 53 { 54 FOR(k,1,len) cnt[a[k]]++; 55 FOR(k,l,r) if(cnt[a[k]]) cnt[a[k]]--; 56 FOR(k,1,len) if(cnt[a[k]]!=0) cnt[a[k]]=0,flg=0; 57 58 } 59 if(flg) ans.push_back(len); 60 FOR(k,1,len) cnt[a[k]]=0; 61 } 62 } 63 int sz=ans.size(); 64 FOR(k,0,sz-1) 65 { 66 if(k!=sz-1) printf("%d ",ans[k]); 67 else printf("%d\n",ans[k]); 68 } 69 } 70 int main() 71 { 72 cin>>T; 73 while(T--) 74 { 75 read(); 76 solve(); 77 } 78 return 0; 79 }
时间: 2024-10-19 23:23:59