A.
考虑前一半异或和等于后一半可以转化为子串异或和为0
然后就做个前缀和,统计奇偶相同的有多少前缀和相同
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define maxn 300005 4 using namespace std; 5 int n; 6 int a[maxn],s[maxn]; 7 map<int,int> mp1,mp2; 8 int main() 9 { 10 scanf("%d",&n); 11 for(int i=1;i<=n;++i)scanf("%d",&a[i]),s[i]=s[i-1]^a[i]; 12 for(int i=0;i<=n;++i) 13 { 14 if(i&1)mp1[s[i]]++; 15 else mp2[s[i]]++; 16 } 17 map<int,int>::iterator it; 18 ll ans=0; 19 for(it=mp1.begin();it!=mp1.end();++it) 20 { 21 ll x=it->second; 22 ans+=x*(x-1)/2; 23 } 24 for(it=mp2.begin();it!=mp2.end();++it) 25 { 26 ll x=it->second; 27 ans+=x*(x-1)/2; 28 } 29 cout<<ans<<endl; 30 return 0; 31 }
B.
考虑一个显然的性质:
因为原串回文,所以从对称位置切,然后调换前后两段,cut次数不超过2(Impossible除外)
然后我们考虑是否有比2更小的答案1;
枚举每个位置暴力判判就行了;
1 #include<bits/stdc++.h> 2 #define maxn 5005 3 using namespace std; 4 char s[maxn],s2[maxn]; 5 bool ispalindrome() 6 { 7 int len=strlen(s2+1); 8 for(int i=1;i<=len;++i)if(s2[i]!=s2[len-i+1])return 0; 9 return 1; 10 } 11 int main() 12 { 13 scanf("%s",s+1); 14 int n=strlen(s+1); 15 int ans=n; 16 for(int i=n/2+((n&1)?1:0);i<=n;++i) 17 { 18 memset(s2,0,sizeof(s2)); 19 int j=n-i; 20 int cnt=0; 21 for(int k=1;k<=j;++k)s2[++cnt]=s[i+k]; 22 for(int k=j+1;k<=i;++k)s2[++cnt]=s[k]; 23 for(int k=i+1;k<=n;++k)s2[++cnt]=s[k-i]; 24 int t=2; 25 if(i==j)t=1; 26 if((strcmp(s+1,s2+1)!=0)&&(ispalindrome()))ans=min(ans,t); 27 } 28 for(int i=1;i<=n;++i) 29 { 30 memset(s2,0,sizeof(s2)); 31 int cnt=0; 32 for(int j=i;j<=n;++j)s2[++cnt]=s[j]; 33 for(int j=1;j<i;++j)s2[++cnt]=s[j]; 34 int t=1; 35 if((strcmp(s+1,s2+1)!=0)&&(ispalindrome()))ans=min(ans,t); 36 } 37 if(ans==n)puts("Impossible"); 38 else printf("%d ",ans); 39 return 0; 40 }
C.
码码码题,留坑
D.
计数题
考虑枚举a,b之间有多少条边,记边数为e;
然后相当于我们在把长度m分成e份,每份为正,这个就是隔板,C(m-1,e-1)
然后考虑中间的点,方案是A(n-2,e-1)
然后考虑其他的点怎么放,这个等价于n个点构成森林,其中有e+1个点两两不处于同一个连通块,由Cayley定理,方案数是f(n,e+1)
其中f(x,y)=y*pow(x,x-y-1)
注意e==n-1时特判,此时方案数为1
最后考虑其他的边,乱选就行,pow(m,n-1-e)
乘上就是最终答案
1 #include<bits/stdc++.h> 2 #define maxn 1000005 3 #define ll long long 4 using namespace std; 5 const ll mod = 1000000007; 6 ll n,m,s,t; 7 ll fac[maxn],invfac[maxn]; 8 ll fastpow(ll a,ll p) 9 { 10 ll ans=1; 11 while(p) 12 { 13 if(p&1)ans=ans*a%mod; 14 a=a*a%mod;p>>=1; 15 } 16 return ans; 17 } 18 ll A(ll x,ll y) 19 { 20 return fac[x]*invfac[x-y]%mod; 21 } 22 ll C(ll x,ll y) 23 { 24 return fac[x]*invfac[y]%mod*invfac[x-y]%mod; 25 } 26 ll f(ll x,ll y) 27 { 28 if(x==y)return 1; 29 return y*fastpow(x,x-y-1)%mod; 30 } 31 int main() 32 { 33 cin>>n>>m>>s>>t; 34 fac[0]=1; 35 for(int i=1;i<=1000000;++i)fac[i]=fac[i-1]*i%mod; 36 for(int i=0;i<=1000000;++i)invfac[i]=fastpow(fac[i],mod-2); 37 ll ans=0; 38 for(int e=1;e<=n-1;++e)if(m>=e) 39 { 40 ans+=A(n-2,e-1)*f(n,e+1)%mod*C(m-1,e-1)%mod*fastpow(m,n-e-1)%mod; 41 ans%=mod; 42 } 43 cout<<ans<<endl; 44 return 0; 45 }