省选摩你35
似乎又垫底了,于是完蛋了,场均切第二题,我就啥也没看出来,打表能力有待提升
T1 Board Game
垃圾博弈dp,压位转移,强行优化
AC_code
#include<bits/stdc++.h>
using namespace std;
// #define int unsigned long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
return s*t;
}
const int N=1<<22;
int n,m,k,h,w;
int id[30][30],cid,u,v;
unsigned long long dp[N],vis[N],zy1[65],zy2[65],a[30][30];
char ch[30];
signed main(){
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
n=read();m=read();k=read();
fo(i,1,n)fo(j,1,m)id[i][j]=++cid;
u=(1<<cid-6)-1;v=(1ull<<64)-1;
fo(kk,1,k){
h=read();w=read();
fo(i,1,h){
scanf("%s",ch+1);
fo(j,1,w)a[i][j]=ch[j]-'0';
}
fo(s,1,n-h+1)fo(t,1,m-w+1){
int zt=0;
fo(i,1,h)fo(j,1,w)zt|=a[i][j]<<(id[i+s-1][j+t-1]-1);
vis[zt>>6]|=(1ull<<(zt&63));
}
}
fo(i,0,63){
fo(j,1,6){
if((i>>j-1&1))zy1[i]|=(1ull<<(i^(1ull<<j-1)));
else zy2[i]|=(1ull<<(i^(1ull<<j-1)));
}
}
fo(s,0,u){
int bit=s;
for(int i=bit;i;i-=(i&-i))vis[s]|=vis[s^(i&-i)];
fo(i,0,63)if(!(vis[s]>>i&1)){
if(zy1[i]&vis[s])vis[s]|=(1ull<<i);
}
}
fu(s,u,0){
int bit=u^s;
for(int i=bit;i;i-=(i&-i))dp[s]|=dp[s^(i&-i)];
fu(i,63,0){
if((vis[s]>>i&1)){
dp[s]&=v^(1ull<<i);
continue;
}
if((zy2[i]&dp[s])!=zy2[i])dp[s]|=(1ull<<i);
}
dp[s]=v^dp[s];
}
printf((dp[0]&1)==0?"Alice":"Bob");
return 0;
}
T2 Function Query
发现操作其实是\(f(a,b) \Longrightarrow f(2*a\%(a+b),2*b\%(a+b))\)
简单推导即可得到操作次数就是(a+b)/gcd(a,b)是2的几次方,如果不是就是无解
于是我们发现这样的数之后\(log^2\)对,于是咋写都行,一种方式是枚举和是多少..
AC_code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
return s*t;
}
const int N=1e5+5;
int n,Q,a[N],ps[N];
struct BIT{
int tr[N];
void ins(int x,int v){
for(int i=x;i<=n;i+=(i&-i))tr[i]+=v;
}
int query(int x){
int ret=0;
for(int i=x;i;i-=(i&-i))ret+=tr[i];
return ret;
}
int qry(int l,int r){
return query(r)-query(l-1);
}
}bit;
struct QU{int l,r,ans;}q[N];
vector<pair<int,int> > vec[N];
vector<int> add[N],del[N];
signed main(){
freopen("func.in","r",stdin);
freopen("func.out","w",stdout);
n=read();
fo(i,1,n)a[i]=read(),ps[a[i]]=i;
Q=read();
fo(i,1,Q){
q[i].l=read();q[i].r=read();
add[q[i].l].push_back(i);
del[q[i].r+1].push_back(i);
}
fo(g,1,n){
for(int i=1;i*g<=n;i+=2){
int now=2,pw=1;
while((now-i)*g<=n){
if(now-i>0&&now-i!=i){
if(ps[i*g]<ps[(now-i)*g])vec[ps[i*g]].push_back(make_pair(ps[(now-i)*g],pw));
else vec[ps[(now-i)*g]].push_back(make_pair(ps[i*g],pw));
}
now*=2;pw++;
}
}
}
fu(i,n,1){
for(pair<int,int> x:vec[i]){
// cerr<<a[i]<<" "<<a[x.first]<<" "<<x.second<<endl;
bit.ins(x.first,x.second);
}
for(int x:del[i])q[x].ans-=bit.qry(q[x].l,q[x].r);
for(int x:add[i])q[x].ans+=bit.qry(q[x].l,q[x].r);
}
fo(i,1,Q)printf("%lld\n",q[i].ans/2);
return 0;
}
T3 Minimal DFA
分析有限状态自动机的性质,这里的字符集是0、1
所以建议看题解,我不知道咋说......
AC_code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
return s*t;
}
const int N=1025;
const int B=1e9;
struct BIG{
vector<int> x;
BIG(){x.push_back(0);}
BIG operator + (BIG a)const{
if(!x.size())return a;
if(!a.x.size())return *this;
BIG ret;ret.x.resize(50);
ret.x[0]=max(x[0],a.x[0]);
int ys=0;
fo(i,1,ret.x[0]){
if(i>x[0])ret.x[i]=a.x[i]+ys;
else if(i>a.x[0])ret.x[i]=x[i]+ys;
else ret.x[i]=x[i]+a.x[i]+ys;
ys=ret.x[i]/B;
ret.x[i]%=B;
}
if(ys)ret.x[++ret.x[0]]=ys;
while(ret.x.size()>ret.x[0]+1)ret.x.pop_back();
return ret;
}
BIG operator - (BIG a)const{
if(!a.x.size())return *this;
BIG ret;ret.x.resize(50);
ret.x[0]=x[0];
fo(i,1,ret.x[0]){
if(i>a.x[0])ret.x[i]+=x[i];
else ret.x[i]+=x[i]-a.x[i];
if(ret.x[i]<0)ret.x[i]+=B,ret.x[i+1]--;
}
while(!ret.x[ret.x[0]]&&ret.x[0]>1)ret.x[0]--;
while(ret.x.size()>ret.x[0]+1)ret.x.pop_back();
return ret;
}
BIG operator + (int a)const{
BIG ret;ret.x.resize(50);
fo(i,0,x[0])ret.x[i]=x[i];
ret.x[1]+=a;
fo(i,1,ret.x[0]){
ret.x[i+1]+=ret.x[i]/B;
ret.x[i]%=B;
}
if(ret.x[ret.x[0]+1])ret.x[0]++;
while(ret.x.size()>ret.x[0]+1)ret.x.pop_back();
return ret;
}
BIG operator - (int a)const{
BIG ret;ret.x.resize(50);
// cerr<<x[0]<<" "<<x[1]<<endl;
fo(i,0,x[0])ret.x[i]=x[i];
// cerr<<ret.x[i]<<" ";cerr<<endl;
// ret=*this;
ret.x[1]-=a;
fo(i,1,ret.x[0]){
if(ret.x[i]<0)ret.x[i]+=B,ret.x[i+1]--;
}
if(!ret.x[ret.x[0]]&&ret.x[0]>1)ret.x[0]--;
while(ret.x.size()>ret.x[0]+1)ret.x.pop_back();
return ret;
}
BIG operator * (int a)const{
BIG ret;ret.x.resize(50);
ret.x[0]=x[0];
fo(i,1,ret.x[0]){
ret.x[i]+=x[i]*a;
ret.x[i+1]+=ret.x[i]/B;
ret.x[i]%=B;
}
while(ret.x[ret.x[0]+1]){
ret.x[0]++;
ret.x[ret.x[0]+1]+=ret.x[ret.x[0]]/B;
ret.x[ret.x[0]]%=B;
}
while(ret.x.size()>ret.x[0]+1)ret.x.pop_back();
return ret;
}
BIG operator * (BIG a)const{
BIG ret;ret.x.resize(50);
ret.x[0]=x[0]+a.x[0]-1;
fo(i,1,x[0])fo(j,1,a.x[0]){
ret.x[i+j-1]+=x[i]*a.x[j];
ret.x[i+j]+=ret.x[i+j-1]/B;
ret.x[i+j-1]%=B;
}
fo(i,1,ret.x[0]){
ret.x[i+1]+=ret.x[i]/B;
ret.x[i]%=B;
}
while(ret.x[ret.x[0]+1]){
// cerr<<ret.x[0]<<endl;
ret.x[0]++;
ret.x[ret.x[0]+1]+=ret.x[ret.x[0]]/B;
ret.x[ret.x[0]]%=B;
}
while(ret.x.size()>ret.x[0]+1)ret.x.pop_back();
return ret;
}
bool operator < (BIG a)const{
if(x[0]<a.x[0])return true;
if(x[0]>a.x[0])return false;
fu(i,x[0],1){
if(x[i]<a.x[i])return true;
if(x[i]>a.x[i])return false;
}
return false;
}
bool operator <= (BIG a)const{
if(x[0]<a.x[0])return true;
if(x[0]>a.x[0])return false;
fu(i,x[0],1){
if(x[i]<a.x[i])return true;
if(x[i]>a.x[i])return false;
}
return true;
}
BIG min(BIG a,BIG b)const{
if(a<b)return a;
return b;
}
void print(){
printf("%lld",x[x[0]]);
fu(i,x[0]-1,1)printf("%09lld",x[i]);
printf(" ");
}
}a[N],b[N],ans,mii,maa,c[N][N];
int n;
void sol1(int ps){
if(ps+1==n)mii=b[ps+1];
else mii=(b[ps+1]+1)*(1ll<<(n-ps-2));
maa=mii+(a[ps+1]-b[ps+1])*(1ll<<(n-ps-1));
}
void sol2(int ps){
if(ps+1==n){
mii=b[ps+1]+1;
maa=b[ps+1]+2;
return ;
}
mii=(b[ps+1]+1)*(1ll<<(n-ps-2));
BIG res=a[ps]-b[ps+1];
fo(i,1,1ll<<n-ps){
BIG now=c[1ll<<n-ps][i]-c[1ll<<n-ps-1][i];
if(res<=now){
mii=mii+res*i;
break;
}
mii=mii+now*i;
res=res-now;
}
maa=(b[ps+1]+1)*(1ll<<(n-ps-2))+(b[ps+1])*(1ll<<(n-ps-1));
res=a[ps]-b[ps+1];
fu(i,1ll<<n-ps,1){
BIG now=c[1ll<<n-ps][i];
if(i>(1ll<<n-ps-1))now=now-c[1ll<<n-ps-1][i-(1ll<<n-ps-1)];
if(res<=now){
maa=maa+res*i;
break;
}
maa=maa+now*i;
res=res-now;
}
}
signed main(){
freopen("dfa.in","r",stdin);
freopen("dfa.out","w",stdout);
n=read();
fo(i,0,1024){
c[i][0].x.resize(2);
c[i][0].x[0]=1;c[i][0].x[1]=1;
fo(j,1,i)c[i][j]=(c[i-1][j-1]+c[i-1][j]);
}
a[0].x.resize(2);
a[0].x[0]=1;a[0].x[1]=1;
fo(i,1,n)a[i]=a[i-1]+a[i-1];
b[n].x.resize(2);
b[n].x[0]=1;b[n].x[1]=1;
fu(i,n-1,0){
b[i]=(b[i+1]+1)*(b[i+1]+1)-1;
if(a[i]<b[i]){
if(a[i]<=b[i+1])sol1(i);
else sol2(i);
fo(j,0,i)ans=ans+a[j];
fo(j,i+1,n)ans=ans+b[j];
break;
}
}
ans.print();mii.print();maa.print();
return 0;
}
QQ:2953174821

浙公网安备 33010602011771号