[考试反思]1017csp-s模拟测试77(lrd day1) :反抗-LMLPHP

[考试反思]1017csp-s模拟测试77(lrd day1) :反抗-LMLPHP

说在前面:强烈谴责AK神Mr_zkt没有丝毫素质RP--

然而我也想没素质一次,但是我没机会AK一套除了B组题以外的题。。。

太菜了,没权力。人家AK了人家就是牛逼你没话说

达哥的题必须好好写反思。

[考试反思]1017csp-s模拟测试77(lrd day1) :反抗-LMLPHP

达哥的题令我恐惧。

之前考的所有达哥的题都不是很难,甚至有AK的,只有我每逢达哥就爆炸。炸得特别惨。

所以今天看到考试标题lrd day1时我就绝望了。

但是这次的题的确还是比较简单,前两题56分钟足以解决。

然后T3被我伪证了,我以为最多每个点周围只有两个联通块。

然后打出来了,128分钟的时候,我觉得我AK了。

但是吸取我这次没有太飘,打对拍。

但是说是在的,效率很低。

然后10分钟拍上T1。

然后T2的暴力死活调不出来,调了45分钟左右才弄出来。

然而其实大样例不水(是最大的一档数据)其实不那么需要对拍。

然后T3的对拍打了一半,发现还有5分钟,就算拍出来了也来不及改了,就挂机了。

然而T3的下发数据很水导致我的伪证没有被hack,而对拍一会就出来了。

考试结束。

总算没有又一次在达哥手下死无全尸。

当有大样例时优先拍大样例比较水的题。

在三道题都打完之后仍然要保持较高的效率打对拍。

话说今天这么简单的话明天的题是不是要跪啊。。。

T1:位运算

大规模手动分类讨论。

 #include<cstdio>
int pre[][][];
int main(){//freopen("ex_bit.in","r",stdin);
pre[][][]=;
pre[][][]=;
pre[][][]=;
int t,XOR,OR,AND;long long ans=;scanf("%d",&t);
while(t--){
scanf("%d%d%d",&AND,&OR,&XOR);ans=;
if(AND!=-&&OR==-&&XOR==-){puts("inf");}
if(AND==-&&OR!=-&&XOR==-){for(int i=;i<;++i)if(OR&<<i)ans*=;printf("%lld\n",ans);}
if(AND==-&&OR==-&&XOR!=-){puts("inf");}
if(AND!=-&&OR!=-&&XOR==-){
for(int i=;i<;++i)if((OR&<<i)==&&(AND&<<i)!=)ans*=;
else if((OR&<<i)!=&&(AND&<<i)==)ans*=;
printf("%lld\n",ans);
}
if(AND!=-&&OR==-&&XOR!=-){
for(int i=;i<;++i)if((XOR&<<i)!=&&(AND&<<i)!=)ans*=;
else if((XOR&<<i)!=&&(AND&<<i)==)ans*=;
printf("%lld\n",ans);
}
if(AND==-&&OR!=-&&XOR!=-){
for(int i=;i<;++i)if((XOR&<<i)!=&&(OR&<<i)==)ans*=;
else if((XOR&<<i)!=&&(OR&<<i)!=)ans*=;
printf("%lld\n",ans);
}
if(AND!=-&&OR!=-&&XOR!=-){
for(int i=;i<;++i)ans*=pre[(AND&<<i)>][(OR&<<i)>][(XOR&<<i)>];
printf("%lld\n",ans);
}
}
}

T2:集合论

套路题。对于加减法开一个全局的标记,然后套一个哈希表就行。

开一个时间戳,求交集的时候更新一下时间戳,这样,时间戳没有被更新的就相当于被删除了。

 #include<cstdio>
struct hash_map{
#define S 20000005
int fir[S],l[S],to[S],w[S],c;
int &operator[](int x){int r=(x+S)%S;
for(int i=fir[r];i;i=l[i])if(to[i]==x)return w[i];
l[++c]=fir[r];fir[r]=c;to[c]=x;return w[c];
}
}M;
char xch,xB[<<],*xS=xB,*xTT=xB;
#define getc() (xS==xTT&&(xTT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xTT)?0:*xS++)
inline int read()
{
int x=,f=;char ch=getc();
while(ch<''|ch>''){if(ch=='-')f=-;ch=getc();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getc();}
return x*f;
}
int main(){//freopen("ex_jihe5.in","r",stdin);freopen("t2.out","w",stdout);
int m=read(),lz=,sz=,cnt=;long long tot=;
while(m--){
int opt=read();
if(opt==){
int x=read(),p;
while(x--){
p=read();
if(M[p-lz]!=cnt)M[p-lz]=cnt,sz++,tot+=p;
}
}else if(opt==){
int x=read(),p;sz=tot=;cnt++;
while(x--){
p=read();
if(M[p-lz]==cnt-)M[p-lz]=cnt,sz++,tot+=p;
}
}else if(opt==)tot+=sz,lz++;
else tot-=sz,lz--;
printf("%lld\n",tot);
}
}

T3:连连看

写的稍工业。

map跑的比哈希表块。

要统计点对,那么就是维护之前扫过的所有块里面和当前块的相邻空块完全一样的,且颜色也一样的个数。

两个点可能会出现有4个相邻空块都相同的情况。

[考试反思]1017csp-s模拟测试77(lrd day1) :反抗-LMLPHP

盗达哥的图2333

所以考虑容斥。奇加偶减。

把每一个点的相邻空块都拆开,写成所有子集的形式。

扫一边,对于每一个位置查一下加一下。

最后统计一下直接相邻的同颜色的贡献。

注意它贡献答案的前提是两者不再任何一个相同的空块里。

码很长,写傻逼了。(子集枚举可以写成状压的,我是手动讨论16种情况。。。)

 #include<cstdio>
#include<map>
using namespace std;
struct P{
int bl1,bl2,bl3,bl4,col;
friend bool operator<(P a,P b){
if(a.col!=b.col)return a.col<b.col;
if(a.bl1!=b.bl1)return a.bl1<b.bl1;
if(a.bl2!=b.bl2)return a.bl2<b.bl2;
if(a.bl3!=b.bl3)return a.bl3<b.bl3;
return a.bl4<b.bl4;
}
};
map<P,int>M;
char xch,xB[<<],*xS=xB,*xTT=xB;
#define getc() (xS==xTT&&(xTT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xTT)?0:*xS++)
inline int read()
{
int x=,f=;char ch=getc();
while(ch<''|ch>''){if(ch=='-')f=-;ch=getc();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getc();}
return x*f;
}
int co[][],n,k,m,al[][],tim,bl[][][];
const int ax[]={,,,-},ay[]={,-,,};
#define tx x+ax[i]
#define ty y+ay[i]
void bfs(int x,int y){
al[x][y]=tim;
if(co[x][y]){
if(!bl[][x][y])bl[][x][y]=tim;
else if(!bl[][x][y])bl[][x][y]=tim;
else if(!bl[][x][y])bl[][x][y]=tim;
else bl[][x][y]=tim;
return;
}
for(int i=;i<=;++i)if(tx>&&ty>&&tx<=n&&ty<=m&&al[tx][ty]!=tim)bfs(tx,ty);
}
int main(){//freopen("ex_link5.in","r",stdin);
n=read();m=read();k=read();long long ans=;
for(int i=;i<=n;++i)for(int j=;j<=m;++j)co[i][j]=read();
for(int i=;i<=n;++i)for(int j=;j<=m;++j)if(co[i][j]==&&al[i][j]==)tim++,bfs(i,j);
for(int i=;i<=n;++i)for(int j=;j<=m;++j)if(co[i][j]){
if(bl[][i][j])
ans+=M[(P){bl[][i][j],,,,co[i][j]}],M[(P){bl[][i][j],,,,co[i][j]}]++;
if(bl[][i][j])
ans+=M[(P){bl[][i][j],,,,co[i][j]}],M[(P){bl[][i][j],,,,co[i][j]}]++,
ans-=M[(P){bl[][i][j],bl[][i][j],,,co[i][j]}],M[(P){bl[][i][j],bl[][i][j],,,co[i][j]}]++;
if(bl[][i][j])
ans+=M[(P){bl[][i][j],,,,co[i][j]}],M[(P){bl[][i][j],,,,co[i][j]}]++,
ans-=M[(P){bl[][i][j],bl[][i][j],,,co[i][j]}],M[(P){bl[][i][j],bl[][i][j],,,co[i][j]}]++,
ans-=M[(P){bl[][i][j],bl[][i][j],,,co[i][j]}],M[(P){bl[][i][j],bl[][i][j],,,co[i][j]}]++,
ans+=M[(P){bl[][i][j],bl[][i][j],bl[][i][j],,co[i][j]}],M[(P){bl[][i][j],bl[][i][j],bl[][i][j],,co[i][j]}]++;
if(bl[][i][j])
ans+=M[(P){bl[][i][j],,,,co[i][j]}],M[(P){bl[][i][j],,,,co[i][j]}]++,
ans-=M[(P){bl[][i][j],bl[][i][j],,,co[i][j]}],M[(P){bl[][i][j],bl[][i][j],,,co[i][j]}]++,
ans-=M[(P){bl[][i][j],bl[][i][j],,,co[i][j]}],M[(P){bl[][i][j],bl[][i][j],,,co[i][j]}]++,
ans-=M[(P){bl[][i][j],bl[][i][j],,,co[i][j]}],M[(P){bl[][i][j],bl[][i][j],,,co[i][j]}]++,
ans+=M[(P){bl[][i][j],bl[][i][j],bl[][i][j],,co[i][j]}],M[(P){bl[][i][j],bl[][i][j],bl[][i][j],,co[i][j]}]++,
ans+=M[(P){bl[][i][j],bl[][i][j],bl[][i][j],,co[i][j]}],M[(P){bl[][i][j],bl[][i][j],bl[][i][j],,co[i][j]}]++,
ans+=M[(P){bl[][i][j],bl[][i][j],bl[][i][j],,co[i][j]}],M[(P){bl[][i][j],bl[][i][j],bl[][i][j],,co[i][j]}]++,
ans-=M[(P){bl[][i][j],bl[][i][j],bl[][i][j],bl[][i][j],co[i][j]}],M[(P){bl[][i][j],bl[][i][j],bl[][i][j],bl[][i][j],co[i][j]}]++;
}
for(int i=;i<=n;++i)for(int j=;j<=m;++j)if(co[i][j]&&co[i][j]==co[i][j-]){
int A=;
for(int k=;k<=;++k)for(int l=;l<=;++l)if(bl[k][i][j-]==bl[l][i][j]&&bl[l][i][j]){A=;break;}
ans+=A;
}
for(int i=;i<=n;++i)for(int j=;j<=m;++j)if(co[i][j]&&co[i][j]==co[i-][j]){
int A=;
for(int k=;k<=;++k)for(int l=;l<=;++l)if(bl[k][i-][j]==bl[l][i][j]&&bl[l][i][j]){A=;break;}
ans+=A;
}
printf("%lld\n",ans);
}

码如砖块

upd:我太傻逼了哈希写崩了!!!手写的哈希表还是要比map快的(2500ms/1570ms)

 #include<cstdio>
struct P{int bl1,bl2,bl3,bl4,col;};
struct hash_map{
int fir[],l[],to_bl1[],to_bl2[];
int to_bl3[],to_bl4[],to_col[],w[],c;
#define mod 100000003
#define g 31313
int &operator[](P x){
int hsh=((((1ll*x.bl1*g+x.bl2)%mod*g+x.bl3)%mod*g+x.bl4)%mod*g+x.col)%mod;
for(int i=fir[hsh];i;i=l[i])if(to_bl1[i]==x.bl1&&to_bl2[i]==x.bl2&&to_bl3[i]==x.bl3&&to_bl4[i]==x.bl4&&to_col[i]==x.col){w[i]++;return w[i];}
l[++c]=fir[hsh];fir[hsh]=c;to_bl1[c]=x.bl1;to_bl2[c]=x.bl2;to_bl3[c]=x.bl3;to_bl4[c]=x.bl4;to_col[c]=x.col;return w[c]=;
}
}M;
char xch,xB[<<],*xS=xB,*xTT=xB;
#define getc() (xS==xTT&&(xTT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xTT)?0:*xS++)
inline int read()
{
int x=,f=;char ch=getc();
while(ch<''|ch>''){if(ch=='-')f=-;ch=getc();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getc();}
return x*f;
}
int co[][],n,k,m,al[][],tim,bl[][][];
const int ax[]={,,,-},ay[]={,-,,};
#define tx x+ax[i]
#define ty y+ay[i]
void bfs(int x,int y){
al[x][y]=tim;
if(co[x][y]){
if(!bl[][x][y])bl[][x][y]=tim;
else if(!bl[][x][y])bl[][x][y]=tim;
else if(!bl[][x][y])bl[][x][y]=tim;
else bl[][x][y]=tim;
return;
}
for(int i=;i<=;++i)if(tx>&&ty>&&tx<=n&&ty<=m&&al[tx][ty]!=tim)bfs(tx,ty);
}
int main(){//freopen("ex_link5.in","r",stdin);
n=read();m=read();k=read();long long ans=;
for(int i=;i<=n;++i)for(int j=;j<=m;++j)co[i][j]=read();
for(int i=;i<=n;++i)for(int j=;j<=m;++j)if(co[i][j]==&&al[i][j]==)tim++,bfs(i,j);
for(int i=;i<=n;++i)for(int j=;j<=m;++j)if(co[i][j]){
if(bl[][i][j])
ans+=M[(P){bl[][i][j],,,,co[i][j]}]-;
if(bl[][i][j])
ans+=M[(P){bl[][i][j],,,,co[i][j]}]-,
ans-=M[(P){bl[][i][j],bl[][i][j],,,co[i][j]}]-;
if(bl[][i][j])
ans+=M[(P){bl[][i][j],,,,co[i][j]}]-,
ans-=M[(P){bl[][i][j],bl[][i][j],,,co[i][j]}]-,
ans-=M[(P){bl[][i][j],bl[][i][j],,,co[i][j]}]-,
ans+=M[(P){bl[][i][j],bl[][i][j],bl[][i][j],,co[i][j]}]-;
if(bl[][i][j])
ans+=M[(P){bl[][i][j],,,,co[i][j]}]-,
ans-=M[(P){bl[][i][j],bl[][i][j],,,co[i][j]}]-,
ans-=M[(P){bl[][i][j],bl[][i][j],,,co[i][j]}]-,
ans-=M[(P){bl[][i][j],bl[][i][j],,,co[i][j]}]-,
ans+=M[(P){bl[][i][j],bl[][i][j],bl[][i][j],,co[i][j]}]-,
ans+=M[(P){bl[][i][j],bl[][i][j],bl[][i][j],,co[i][j]}]-,
ans+=M[(P){bl[][i][j],bl[][i][j],bl[][i][j],,co[i][j]}]-,
ans-=M[(P){bl[][i][j],bl[][i][j],bl[][i][j],bl[][i][j],co[i][j]}]-;
}
for(int i=;i<=n;++i)for(int j=;j<=m;++j)if(co[i][j]&&co[i][j]==co[i][j-]){
int A=;
for(int k=;k<=;++k)for(int l=;l<=;++l)if(bl[k][i][j-]==bl[l][i][j]&&bl[l][i][j]){A=;break;}
ans+=A;
}
for(int i=;i<=n;++i)for(int j=;j<=m;++j)if(co[i][j]&&co[i][j]==co[i-][j]){
int A=;
for(int k=;k<=;++k)for(int l=;l<=;++l)if(bl[k][i-][j]==bl[l][i][j]&&bl[l][i][j]){A=;break;}
ans+=A;
}
printf("%lld\n",ans);
}

但它还是个砖块

upd2:稍优化了一下。1450ms。码长总算降到了2.8k。(手动讨论占了一半。。。)

 #include<cstdio>
struct P{int bl1,bl2,bl3,bl4,col;};
struct hash_map{
int fir[],l[],to_col[],w[],c;
#define mod 100000003
#define g 31313
int &operator[](P x){
int hsh=((((1ll*x.bl1*g+x.bl2)*g+x.bl3)%mod*g+x.bl4)*g+x.col)%mod;
for(int i=fir[hsh];i;i=l[i])if(to_col[i]==x.col){w[i]++;return w[i];}
l[++c]=fir[hsh];fir[hsh]=c;to_col[c]=x.col;return w[c]=;
}
}M;
char xch,xB[<<],*xS=xB,*xTT=xB;
#define getc() (xS==xTT&&(xTT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xTT)?0:*xS++)
inline int read()
{
int x=,f=;char ch=getc();
while(ch<''|ch>''){if(ch=='-')f=-;ch=getc();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getc();}
return x*f;
}
int co[][],n,k,m,al[][],tim,bl[][][];
const int ax[]={,,,-},ay[]={,-,,};
#define tx x+ax[i]
#define ty y+ay[i]
void bfs(int x,int y){
al[x][y]=tim;
if(co[x][y]){
if(!bl[][x][y])bl[][x][y]=tim;
else if(!bl[][x][y])bl[][x][y]=tim;
else if(!bl[][x][y])bl[][x][y]=tim;
else bl[][x][y]=tim;
return;
}
for(int i=;i<=;++i)if(tx>&&ty>&&tx<=n&&ty<=m&&al[tx][ty]!=tim)bfs(tx,ty);
}
int main(){//freopen("ex_link5.in","r",stdin);
n=read();m=read();k=read();long long ans=;
for(int i=;i<=n;++i)for(int j=;j<=m;++j)co[i][j]=read();
for(int i=;i<=n;++i)for(int j=;j<=m;++j)if(co[i][j]==&&al[i][j]==)tim++,bfs(i,j);
for(int i=;i<=n;++i)for(int j=;j<=m;++j)if(co[i][j]){
if(bl[][i][j])
ans+=M[(P){bl[][i][j],,,,co[i][j]}]-;
if(bl[][i][j])
ans+=M[(P){bl[][i][j],,,,co[i][j]}]-,
ans-=M[(P){bl[][i][j],bl[][i][j],,,co[i][j]}]-;
if(bl[][i][j])
ans+=M[(P){bl[][i][j],,,,co[i][j]}]-,
ans-=M[(P){bl[][i][j],bl[][i][j],,,co[i][j]}]-,
ans-=M[(P){bl[][i][j],bl[][i][j],,,co[i][j]}]-,
ans+=M[(P){bl[][i][j],bl[][i][j],bl[][i][j],,co[i][j]}]-;
if(bl[][i][j])
ans+=M[(P){bl[][i][j],,,,co[i][j]}]-,
ans-=M[(P){bl[][i][j],bl[][i][j],,,co[i][j]}]-,
ans-=M[(P){bl[][i][j],bl[][i][j],,,co[i][j]}]-,
ans-=M[(P){bl[][i][j],bl[][i][j],,,co[i][j]}]-,
ans+=M[(P){bl[][i][j],bl[][i][j],bl[][i][j],,co[i][j]}]-,
ans+=M[(P){bl[][i][j],bl[][i][j],bl[][i][j],,co[i][j]}]-,
ans+=M[(P){bl[][i][j],bl[][i][j],bl[][i][j],,co[i][j]}]-,
ans-=M[(P){bl[][i][j],bl[][i][j],bl[][i][j],bl[][i][j],co[i][j]}]-;
}
for(int i=;i<=n;++i)for(int j=;j<=m;++j)if(co[i][j]&&co[i][j]==co[i][j-]){
int A=;
for(int k=;k<=;++k)for(int l=;l<=;++l)if(bl[k][i][j-]==bl[l][i][j]&&bl[l][i][j]){A=;break;}
ans+=A;
}
for(int i=;i<=n;++i)for(int j=;j<=m;++j)if(co[i][j]&&co[i][j]==co[i-][j]){
int A=;
for(int k=;k<=;++k)for(int l=;l<=;++l)if(bl[k][i-][j]==bl[l][i][j]&&bl[l][i][j]){A=;break;}
ans+=A;
}
printf("%lld\n",ans);
}

不要想了还是砖块

05-22 03:59