暑假集训test-8-26

真 noip模拟题

但是被我做得稀巴烂

新高二除了林巨做得勉强能看,其他人都做得稀巴烂

老张都要绝望了

 

t1.水呀水

题如其名是道水题。新建个点代表水源,跑最小生成树即可。

 1 //Achen
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<vector>
 7 #include<cstdio>
 8 #include<queue>
 9 #include<cmath>
10 #include<set>
11 #include<map>
12 #define Formylove return 0
13 #define For(i,a,b) for(int i=(a);i<=(b);i++)
14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
15 const int N=200007;
16 typedef long long LL;
17 typedef double db;
18 using namespace std;
19 int n,m,ecnt;
20 char s[N];
21 
22 template<typename T>void read(T &x)  {
23     char ch=getchar(); x=0; T f=1;
24     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
25     if(ch=='-') f=-1,ch=getchar();
26     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
27 }
28 
29 struct edge {
30     int u,v,w;
31     edge(){}
32     edge(int u,int v,int w):u(u),v(v),w(w){}
33     friend bool operator <(const edge&A,const edge&B) {
34         return A.w<B.w;
35     }
36 }e[N<<1];
37 
38 int fa[N];
39 int find(int x) { return x==fa[x]?x:fa[x]=find(fa[x]); }
40 
41 LL kruskal(int n) {
42     LL rs=0;
43     int tot=0;
44     For(i,1,n) fa[i]=i; 
45     For(i,1,ecnt) {
46         int u=e[i].u,v=e[i].v,w=e[i].w;
47         int x=find(u),y=find(v);
48         if(x!=y) {
49             tot++;
50             rs+=w;
51             fa[x]=y;
52             if(tot==n-1) break;
53         }
54     }
55     return tot==n-1?rs:-1;
56 }
57 
58 #define ANS
59 int main() {
60 #ifdef ANS
61     freopen("water.in","r",stdin);
62     freopen("water.out","w",stdout);
63 #endif
64     read(n); 
65     scanf("%s",s+1);
66     For(i,1,n) if(s[i]=='1') e[++ecnt]=edge(n+1,i,0);
67     For(i,1,n) {
68         int w; read(w);
69         if(s[i]=='0'&&w!=-1) e[++ecnt]=edge(n+1,i,w);
70     }
71     read(m);
72     For(i,1,m) {
73         int u,v,w;
74         read(u); read(v); read(w);
75         e[++ecnt]=edge(u,v,w);
76     }
77     sort(e+1,e+ecnt+1);
78     LL ans=kruskal(n+1); 
79     if(ans==-1) puts("Are you kidding me");
80     else printf("%lld
",ans);
81     Formylove;
82 }
View Code

 

t2浪呀浪

一开始想这道题的时候脑子抽了,在这道题花的时间太长了,实际上除了注意细节就是道水题啊。

最后十几分钟才码出正解,大样例都没过就交了,结果i+k,j+k,i-k,j-k各种数组越界炸成40。

于是定义了个函数来找判断i,j是否越界。

 

题解:发现一定可以找到一条横着的或者竖着的线使得两个矩形在线一边另一个矩形在线另一边,处理出左上左下右上右下四个二维前缀最大值数组,横竖左右扫四遍即可得答案。

//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define Formylove return 0
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
const int N=1507;
typedef long long LL;
typedef double db;
using namespace std;
int n,m,k,a[N][N],b[N][N],c[N][N],ans;
int zs[N][N],zx[N][N],ys[N][N],yx[N][N];

template<typename T>void read(T &x)  {
    char ch=getchar(); x=0; T f=1;
    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    if(ch=='-') f=-1,ch=getchar();
    for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}

int ok(int x,int y,int xx,int yy) {
    return max(abs(x-xx),abs(y-yy))>=k;
}

int ck(int i,int j) { return i>=1&&i<=n&&j>=1&&j<=m; }

int ZS(int i,int j) { return ck(i,j)?zs[i][j]:0; }
int ZX(int i,int j) { return ck(i,j)?zx[i][j]:0; }
int YS(int i,int j) { return ck(i,j)?ys[i][j]:0; }
int YX(int i,int j) { return ck(i,j)?yx[i][j]:0; }

#define ANS
int main() {
#ifdef ANS
    freopen("wave.in","r",stdin);
    freopen("wave.out","w",stdout);
#endif
    read(n); read(m); read(k);
    For(i,1,n) For(j,1,m) read(a[i][j]);
    For(i,1,n) {
        int sum=0;
        For(j,1,m) {
            sum+=a[i][j];
            b[i][j]=b[i-1][j]+sum;
        }
    } 
    For(i,k,n) For(j,k,m) c[i][j]=b[i][j]-b[i-k][j]-b[i][j-k]+b[i-k][j-k];
    For(i,1,n) {
        int sum=0;
        For(j,1,m) {
            sum=max(sum,c[i][j]);
            zs[i][j]=max(zs[i-1][j],sum);
        }
    }
    For(i,1,n) {
        int sum=0;
        Rep(j,m,1) {
            sum=max(sum,c[i][j]);
            ys[i][j]=max(ys[i-1][j],sum);
        }
    }
    Rep(i,n,1) {
        int sum=0;
        For(j,1,m) {
            sum=max(sum,c[i][j]);
            zx[i][j]=max(zx[i+1][j],sum);
        }
    }
    Rep(i,n,1) {
        int sum=0;
        Rep(j,m,1) {
            sum=max(sum,c[i][j]);
            yx[i][j]=max(yx[i+1][j],sum);
        }
    }
        
    int tp=0;
    For(i,k,n) {
        For(j,k,m) {
            int tpp=max(max(ZS(i,j-k),ZS(i-k,m)),YS(i,j+k))+c[i][j];
            tp=max(tp,tpp);
            ans=max(ans,tp+ZX(i+k,m));
        }
    }
    tp=0;
    Rep(i,n,k) {
        For(j,k,m) {
            int tpp=max(max(ZX(i,j-k),ZX(i+k,m)),YX(i,j+k))+c[i][j];
            tp=max(tp,tpp);
            ans=max(ans,tp+ZS(i-k,m)); 
        }
    }
    tp=0;
    For(j,k,m) {
        For(i,k,n) {
            int tpp=max(max(ZS(i-k,j),ZS(n,j-k)),ZX(i+k,j))+c[i][j];
            tp=max(tp,tpp);
            ans=max(ans,tp+YS(n,j+k));
        }
    } 
    tp=0;
    Rep(j,m,k) {
        For(i,k,n) {
            int tpp=max(max(YS(i-k,j),YS(n,j+k)),YX(i+k,j))+c[i][j];
            tp=max(tp,tpp);
            ans=max(ans,tp+ZS(n,j-k));
        }
    }
    printf("%d
",ans);
    Formylove;
}
View Code

 

t3跳呀跳

太菜了,不说什么了。

容易想到确定一行一列就可以确定整个矩阵,然后限制不知道怎么用。

1的个数为奇数,我竟然没有往异或上想,大概是个智障吧。

枚举a1,然后根据限制用带权并查集维护a1~a_{n+m-1}之间的关系即可。

对于直接限制a1~a_{n+m-1}的可以新建点a_{n+m}代表权值为0

 1 //Achen
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<vector>
 7 #include<cstdio>
 8 #include<queue>
 9 #include<cmath>
10 #include<set>
11 #include<map>
12 #define Formylove return 0
13 #define For(i,a,b) for(int i=(a);i<=(b);i++)
14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
15 const int p=1e9+7,N=2e6+7;
16 typedef long long LL;
17 typedef double db;
18 using namespace std;
19 int n,m,k,x[N],y[N],w[N];
20 
21 template<typename T>void read(T &x)  {
22     char ch=getchar(); x=0; T f=1;
23     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
24     if(ch=='-') f=-1,ch=getchar();
25     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
26 }
27 
28 LL ksm(LL a,LL b) {
29     LL rs=1,bs=a;
30     while(b) {
31         if(b&1) rs=rs*bs%p;
32         bs=bs*bs%p;
33         b>>=1;
34     }
35     return rs;
36 }
37 
38 int fa[N],fdis[N];
39 int find(int x) {
40     if(x==fa[x]) return x;
41     int y=find(fa[x]);
42     fdis[x]^=fdis[fa[x]];
43     fa[x]=y; return y;
44 }
45 
46 LL solve(int o) {
47     For(i,1,n+m) fa[i]=i,fdis[i]=0; //n+m:0
48     For(i,1,k) {
49         int u=x[i]+m-1,v=y[i],ww=w[i];
50         int fu=find(u),fv=find(v);
51         if(x[i]==1&&y[i]==1) continue;
52         if(x[i]==1||y[i]==1) {
53             if(y[i]==1) swap(u,v),swap(fu,fv);
54             if(fv==n+m&&fdis[v]!=ww) return 0;
55             if(fv!=n+m) {
56                 fa[fv]=n+m; 
57                 fdis[fv]=(fdis[v]^ww);
58             }
59         }
60         else if(fu==fv) {
61             if((ww^o^1^fdis[u]^fdis[v])!=0) return 0;
62             else continue;
63         }
64         else {
65             if(fu==n+m) swap(u,v),swap(fu,fv);
66             fa[fu]=fv; 
67             fdis[fu]=(ww^o^1^fdis[u]^fdis[v]);
68         }
69     }
70     LL rs=0;
71     For(i,2,n+m-1) if(find(i)==i) 
72         rs++;
73     return ksm(2LL,rs);
74 }
75 
76 #define ANS
77 int main() {
78 #ifdef ANS
79     freopen("jump.in","r",stdin);
80     freopen("jump.out","w",stdout);
81 #endif
82     read(n); read(m); read(k);
83     int fl=-1;
84     For(i,1,k) {
85         read(x[i]); read(y[i]); read(w[i]);
86         if(x[i]==1&&y[i]==1) fl=w[i];
87     }
88     LL ans;
89     if(fl==-1) ans=(solve(1)+solve(0))%p; 
90     else ans=solve(fl);
91     printf("%lld
",ans);
92     Formylove;
93 }
View Code

 

 

原文地址:https://www.cnblogs.com/Achenchen/p/9540531.html