小细节卡的挺难受呀 A. Subtle Substring Subtraction
Alice肯定一下取走尽可能多的数
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
char s[N];
int main()
{
int t;
cin>>t;
while(t--)
{
int sum=0;
scanf("%s",s+1);
int l=strlen(s+1);
for(int i=1;i<=l;i++) sum+=s[i]-'a'+1;
if(l%2==0) cout<<"Alice "<<sum<<endl;
else{
int L=sum-min(s[l]-'a'+1,s[1]-'a'+1);
if(L>sum-L)cout<<"Alice "<<2*L-sum<<endl;
else cout<<"Bob "<<sum-2*L<<endl;
}
}
}
每个字母都有可能成为多一的那个,但是任意两个相邻相同字母之间都存在其他字母的时候那么他就不会是那个字母
B. A Perfectly Balanced String?
#include<bits/stdc++.h>
using namespace std;
int a[30];
bool c[30];
char s[200010];
int main()
{
int t;
cin>>t;
while(t--)
{
int sum=0;
scanf("%s",s+1);
int l=strlen(s+1);
for(int i=0;i<30;i++) a[i]=c[i]=0;
for(int i=1;i<=l;i++) c[s[i]-'a']=1;
for(int i=0;i<30;i++) sum+=c[i],c[i]=0;
bool ans=1;
for(int i=1;i<=l;i++)
{
int p=s[i]-'a';
if(c[p]&&i-a[p]<sum) ans=0;
a[p]=i;
c[p]=1;
}
if(ans) puts("YES");
else puts("NO");
}
}
C. Palindrome Basis
动态规划,枚举构成最大值
#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
vector<int> a;
int sz;
bool check(int x){
vector<int> b;
while(x){
b.push_back(x%10);
x/=10;
}
int SZ=b.size();
for(int i=0;i<SZ/2;i++)
if(b[i]!=b[SZ-i-1]) return false;
return true;
}
int ans[40010];
int main()
{
for(int i=1;i<=40000;i++) if(check(i)) a.push_back(i);sz=a.size();
ans[0]=1;
for(int i=0;i<sz;i++)
{
for(int j=a[i];j<=40000;j++)
{
ans[j]+=ans[j-a[i]];
if(ans[j]>=mod) ans[j]-=mod;
}
}
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
cout<<ans[n]<<endl;
}
}
D. Lost Arithmetic Progression
暴力枚举因数计算结果 yy不是y的倍数或者两个序列并不同轨那么也会不会交的,答案为0 如果C在B的边缘那么答案是无穷的 可行区间左右对称,平方加和即可
#include<iostream>
using namespace std;
typedef long long ll;
ll gcd(ll x,ll y)
{
while(y) y^=x^=y^=x%=y;
return x;
}
const int mod=1e9+7;
int main()
{
int t;
cin>>t;
while(t--)
{
ll x,y,z;
ll xx,yy,zz;
cin>>x>>y>>z;
cin>>xx>>yy>>zz;
if(yy%y!=0||xx<x||x+(z-1)*y<xx+(zz-1)*yy||(x-xx)%y!=0) cout<<0<<endl;
else if(x>xx-yy||x+(z-1)*y<xx+zz*yy) cout<<-1<<endl;
else
{
ll g=yy/y;
while(g*y/gcd(g,y)!=yy) g=yy/y*gcd(g,y);
ll p=y/gcd(y,g);
ll ans=0;
for(ll i=1;i*i<=p;i++)
{
if(p%i==0)
{
if(p/i==i) ans+=i*i;
else ans+=i*i+p/i*p/i;
ans%=mod;
}
}
cout<<ans<<endl;
}
}
}
E. Power or XOR?
taps 每段区间的长度不会超过21 所以可以暴力的枚举每一段区间,每一段的区间指数<1e6,大的会被模掉,对答案不产生影响 对于每一段,通过组合数计算出现奇偶次数,偶数次XOR=0;对答案不产生影响,对于奇数次位置XOR1 组合数的奇偶性可以暴力求那一段可行区间的,也可以使用C(l,r)=C(l-1,r)+C(l-1,r-1); +C(l,r…l)=C(l,r)+2*K+C(l,l);因此计算两边的奇偶性即可
补上一个高级的判定方法若l&r=r,则C为奇数,否则为偶数
#include<iostream>
using namespace std;
typedef long long ll;
const int N=2e6+10;
const int MAX=1024*1024;
int c2[N],b[N],b2[N],ans[N],base;
ll pb[N];
bool f[31][N];
int pf[31][N];
bool check(int l,int r)
{
if(r>l) return 0;
if(r==0) return pf[l-base][l]&1;
return (pf[l-base][l]-pf[l-base][r-1])&1;
}
bool check2(int l,int r)
{
if(r>l) return 0;
return !(c2[l]-c2[l-r]-c2[r]);
}
int ksm(int x,int y)
{
int ans=1;
while(y){
if(y&1) ans=ans*x;
y>>=1;
x*=x;
}
return ans;
}
void cal(int l,int r,int cl,int cr)
{
if(check(cl,cr)&&pb[r]-pb[l]+b2[l]<20){
int idx=ksm(2,pb[r]-pb[l])*b[l];
ans[idx]^=1;
}
}
int read()
{
int ans=0;
char c=getchar();
while(c==' '||c=='\n') c=getchar();
while(c>='0'&&c<='9') ans=ans*10+c-'0',c=getchar();
return ans;
}
int main()
{
for(int i=1;i<N;i++){
int p=i;
c2[i]+=c2[i-1];
while((p&1)==0) c2[i]++,p>>=1;
}
int n,k;
cin>>n>>k;
base=max(n-30,0);
for(int i=max(0,n-30);i<=n;i++)
for(int j=0;j<=n;j++){
f[i-base][j]=check2(i,j);
if(j==0) pf[i-base][j]=f[i-base][j];
else pf[i-base][j]=pf[i-base][j-1]+f[i-base][j];
}
for(int i=1;i<=n;i++){
b[i]=read();
pb[i]=pb[i-1]+b[i];
int p=b[i];p>>=1;
while(p) b2[i]++,p>>=1;
}
if(k==0) cal(1,n,0,0);
k=max(k,1);
for(int j=1;j<min(n,25);j++) cal(1,j,n-j-1,k-1);
for(int j=max(2,n-25);j<=n;j++) cal(j,n,j-2,k-1);
k=max(k,2);
for(int i=2;i<=n-1;i++)
for(int j=1;j<=25&&i+j-1<n;j++)
cal(i,i+j-1,n-j-2,k-2);
bool zero=1;
for(int i=N;i>=0;i--){
if(ans[i]) zero=0;
if(!zero) printf("%d",ans[i]);
}
if(zero) cout<<0;
puts("");
}
#include<iostream>
using namespace std;
typedef long long ll;
const int N=2e6+10;
const int MAX=1024*1024;
int c2[N],b[N],b2[N],ans[N],st[N];
ll pb[N];
bool check(int l,int r)
{
if(r>l) return 0;
if(l==0) return 1;
if(r==0) return 0;
return !(((l-1)&(r-1))^(r-1));
}
int ksm(int x,int y)
{
int ans=1;
while(y){
if(y&1) ans=ans*x;
y>>=1;
x*=x;
}
return ans;
}
bool cal(int l,int r,int cl,int cr)
{
if(pb[r]-pb[l]+b2[l]>=20) return 0;
if(check(cl,cr)){
int idx=ksm(2,pb[r]-pb[l])*b[l];
ans[idx]^=1;
}
return 1;
}
int read()
{
int ans=0;
char c=getchar();
while(c==' '||c=='\n') c=getchar();
while(c>='0'&&c<='9') ans=ans*10+c-'0',c=getchar();
return ans;
}
int main()
{
int n,k;
cin>>n>>k;
for(int i=0;(1<<i)<=MAX;i++) st[1<<i]=i;
for(int i=1;i<=MAX;i++) if(!st[i]) st[i]=st[i-1];
for(int i=1;i<=n;i++){
b[i]=read();
pb[i]=pb[i-1]+b[i];
b2[i]=st[b[i]];
}
if(k==0) cal(1,n,0,0);
k=max(k,1);
for(int j=1;j<min(n,25);j++) if(!cal(1,j,n-j-1,k-1)) break;
for(int j=n;j>=max(2,n-25);j--) if(!cal(j,n,j-2,k-1)) break;
k=max(k,2);
for(int i=2;i<=n-1;i++)
for(int j=1;j<=25&&i+j-1<n;j++)
if(!cal(i,i+j-1,n-j-2,k-2)) break;
bool zero=1;
for(int i=MAX;i>=0;i--){
if(ans[i]) zero=0;
if(!zero) printf("%d",ans[i]);
}
if(zero) cout<<0;
puts("");
}
F. Anti-Theft Road Planning
我们尽量把高位相同放在一块 想办法让每个节点唯一代表一个值并且相邻两数的异或和尽可能小 对于32*32;把他分成四分,最高两位一致的放在四个角上 其次对于矩阵的四份做一个上下左右对称,这样位于边界上的数除了最高位不同以外,其他位相同 依次分型递推
#include<iostream>
using namespace std;
int s[50][50];
int mp[50][50][2];
int ans[2000][2];
void cp(int x,int y,int xx,int yy,int n,int p,int xj,int yj)
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
s[xx+i*xj][yy+j*yj]=s[x+i][y+j]+p;
}
void build(int x)
{
if(x==0) return ;
build(x-1);
cp(1,1,1,1<<x,(1<<(x-1)),1<<2*(x-1),1,-1);
cp(1,1,1<<x,1,(1<<(x-1)),2<<2*(x-1),-1,1);
cp(1,1,1<<x,1<<x,(1<<(x-1)),3<<2*(x-1),-1,-1);
}
int main()
{
int n,k,idx=0;
cin>>n;
build(5);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(j>1) mp[i][j][0]=s[i][j]^s[i][j-1];
if(i>1) mp[i][j][1]=s[i][j]^s[i-1][j];
ans[s[i][j]][0]=i;
ans[s[i][j]][1]=j;
}
}
for(int i=1;i<=n;i++){
for(int j=2;j<=n;j++) cout<<mp[i][j][0]<<' ';
puts("");
}
for(int i=2;i<=n;i++){
for(int j=1;j<=n;j++) cout<<mp[i][j][1]<<' ';
puts("");
}
cin>>k;
while(k--)
{
int mod;
cin>>mod;
idx^=mod;
cout<<ans[idx][0]<<' '<<ans[idx][1]<<endl;
}
}
|