AtCoder Grand Contest 023

比赛链接

由于太菜了考场上没有想出C,并且还没有补完EF ><

A - Zero-Sum Ranges

记录前缀和开map统计即可。

#include<bits/stdc++.h>
#define rep(i,x,y) for (int i=(x); i<=(y); i++)
#define per(i,x,y) for (int i=(x); i>=(y); i--)
#define ll long long
#define ull unsigned long long
#define ld long double
#define inf 1000000000
#define INF 1000000000000000000ll
#define pii pair<int,int>
#define F first
#define S second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define sqr(x) ((x)*(x))
#define y1 y1_
#define cmin(x,y) (x)=(y)<(x)?(y):(x)
#define cmax(x,y) (x)=(y)>(x)?(y):(x)
#define mset(x,y) memset((x),(y),sizeof(x))
#define mcpy(x,y) memcpy((x),(y),sizeof(y))
using namespace std;
const ld pi=acos(-1);
const ld eps=1e-8;
 header files 
ll read(){
    char ch=getchar(); ll x=0; int op=1;
    for (; !isdigit(ch); ch=getchar()) if (ch=='-') op=-1;
    for (; isdigit(ch); ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
    return x*op;
}
void write(ll a){
    if (a<0) putchar('-'),a=-a;
    if (a>=10) write(a/10); putchar(a%10+'0');
}
// fast i/o //
#ifdef mod
ll ksm(ll x,ll p){
    ll ret=1;
    for (; p; p>>=1,x=x*x%mod) if (p&1) ret=ret*x%mod;
    return ret;
}
ll getinv(ll x){ return ksm(x,mod-2); }
#else
ll ksm(ll x,ll p){
    ll ret=1;
    for (; p; p>>=1,x=x*x) if (p&1) ret=ret*x;
    return ret;
}
#endif
 qpow 
#define N 200005
int n; ll a[N],ans;
map<ll,int> Mp;
//#define local
int main(){
#ifdef local
    freopen("test.in","r",stdin); freopen("test.out","w",stdout);
#endif
    n=read(); Mp[0]=1;
    rep (i,1,n){
        a[i]=a[i-1]+read();
        ans+=Mp[a[i]]; Mp[a[i]]++;
    }
    cout<<ans<<endl;
    return 0;
}
// sample data:
/*

*/

// rest:
/*

*/

B - Find Symmetries

行和列分别hash即可。

#include<bits/stdc++.h>
#define rep(i,x,y) for (int i=(x); i<=(y); i++)
#define per(i,x,y) for (int i=(x); i>=(y); i--)
#define ll long long
#define ull unsigned long long
#define ld long double
#define inf 1000000000
#define INF 1000000000000000000ll
#define pii pair<int,int>
#define F first
#define S second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define sqr(x) ((x)*(x))
#define y1 y1_
#define cmin(x,y) (x)=(y)<(x)?(y):(x)
#define cmax(x,y) (x)=(y)>(x)?(y):(x)
#define mset(x,y) memset((x),(y),sizeof(x))
#define mcpy(x,y) memcpy((x),(y),sizeof(y))
using namespace std;
const ld pi=acos(-1);
const ld eps=1e-8;
 header files 
ll read(){
    char ch=getchar(); ll x=0; int op=1;
    for (; !isdigit(ch); ch=getchar()) if (ch=='-') op=-1;
    for (; isdigit(ch); ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
    return x*op;
}
void write(ll a){
    if (a<0) putchar('-'),a=-a;
    if (a>=10) write(a/10); putchar(a%10+'0');
}
// fast i/o //
#ifdef mod
ll ksm(ll x,ll p){
    ll ret=1;
    for (; p; p>>=1,x=x*x%mod) if (p&1) ret=ret*x%mod;
    return ret;
}
ll getinv(ll x){ return ksm(x,mod-2); }
#else
ll ksm(ll x,ll p){
    ll ret=1;
    for (; p; p>>=1,x=x*x) if (p&1) ret=ret*x;
    return ret;
}
#endif
 qpow 
#define N 605
#define base 233
#define mod 20030731
int n,h1[N][N],h2[N][N],pw[N],ans; char a[N][N];
int gethash1(int x,int s,int t){ return (h1[x][t]+mod-(ll)h1[x][s-1]*pw[t-s+1]%mod)%mod; }
int gethash2(int x,int s,int t){ return (h2[x][t]+mod-(ll)h2[x][s-1]*pw[t-s+1]%mod)%mod; }
//#define local
int main(){
#ifdef local
    freopen("test.in","r",stdin); freopen("test.out","w",stdout);
#endif
    n=read();
    rep (i,1,n){
        scanf("%s",a[i]+1);
        rep (j,1,n) a[i+n][j]=a[i][j+n]=a[i+n][j+n]=a[i][j];
    }
    rep (i,1,2*n){
        h1[i][0]=0;
        rep (j,1,2*n) h1[i][j]=((ll)h1[i][j-1]*base+a[i][j])%mod;
    }
    rep (j,1,2*n){
        h2[j][0]=0;
        rep (i,1,2*n) h2[j][i]=((ll)h2[j][i-1]*base+a[i][j])%mod;
    }
    pw[0]=1; rep (i,1,2*n) pw[i]=(ll)pw[i-1]*base%mod;
    rep (i,1,n) rep (j,1,n){
        bool flag=1;
        rep (k,1,n) if (gethash1(i+k-1,j,j+n-1)!=gethash2(j+k-1,i,i+n-1)) flag=0;
        ans+=flag;
    }
    cout<<ans<<endl;
    return 0;
}
// sample data:
/*

*/

// rest:
/*

*/

C - Painting Machines

考虑求出 f[i] f [ i ] 表示覆盖i次使得全部的点被覆盖的方案数。

发现每个点被覆盖的次数只会是1或2,并且两个2之间1的个数必须是偶数,特别的,两端的1个数位奇数,并且1和n的位置上只会是1。

所以可以除掉1和n位置上的1,剩下的1中要在相隔偶数的位置插入2,可以组合数算。

注意这个 f[i] f [ i ] 求出的是所有长为 i i 的完全覆盖的排列数,有可能是在 i 时已经完全覆盖,需要减去 f[i1] f [ i − 1 ]

#include<bits/stdc++.h>
#define rep(i,x,y) for (int i=(x); i<=(y); i++)
#define per(i,x,y) for (int i=(x); i>=(y); i--)
#define ll long long
#define ull unsigned long long
#define ld long double
#define inf 1000000000
using namespace std;
#define N 1000005
#define mod 1000000007
int n,fac[N],inv[N],f[N],ans;
int ksm(int x,int p){
    int ret=1;
    for (; p; p>>=1,x=(ll)x*x%mod) if (p&1) ret=(ll)ret*x%mod;
    return ret;
}
int getinv(int x){ return ksm(x,mod-2); }
int C(int n,int m){ return (ll)fac[n]*inv[n-m]%mod*inv[m]%mod; }
int main(){
    scanf("%d",&n);
    fac[0]=1; rep (i,1,n) fac[i]=(ll)fac[i-1]*i%mod;
    inv[n]=getinv(fac[n]); per (i,n-1,0) inv[i]=(ll)inv[i+1]*(i+1)%mod;
    rep (i,(n+1)/2,n-1){
        f[i]=(ll)fac[i]*fac[n-1-i]%mod*C(2*i-n+(n-2-(2*i-n))/2,2*i-n)%mod;
        ans=(ans+(ll)(f[i]+mod-f[i-1])*i%mod)%mod;
    }
    cout<<ans<<endl;
    return 0;
}

D - Go Home

很巧妙的一个题!

发现汽车访问过的点是一个连续区间。所以如果s在n号点右边或1号点左边,肯定是直接走到另一端就行了。

假如s在1~n之间,那么考虑1和n两个点,如果 P1Pn P 1 ≥ P n ,那么1肯定比n先访问到。因为如果要访问n,一定会途径n-1,经过n-1以后投票给正方向的人数只剩下了 Pn P n ,投票给负方向的人数 P1 ≥ P 1 ,而 P1Pn P 1 ≥ P n ,所以此时一定会走向1。

那么我们进行这样的操作:如果 P1Pn P 1 ≥ P n ,将 ans+=X[n]-X[1],然后 P[1]+=P[n],n--; 直到 P1<Pn P 1 < P n

也就是说n左移过的那几个点,都是由最后一次 1n 1 → n 访问到的。

当然如果是 P1<Pn P 1 < P n ,情况是类似的。

然后再进行下一轮即可。直到【s在n号点右边或1号点左边】的时候停止。

25行代码。

#include<bits/stdc++.h>
#define rep(i,x,y) for (int i=(x); i<=(y); i++)
#define ll long long
#define ld long double
#define inf 1000000000
#define N 100005
int n,s; ll a[N],b[N],ans;
int main(){
    scanf("%d%d",&n,&s);
    rep (i,1,n) scanf("%d%d",&a[i],&b[i]);
    int l=1,r=n; ans=0;
    while (l<=r){
        if (s<=a[l]){ ans+=a[r]-s; break; }
        if (s>=a[r]){ ans+=s-a[l]; break; }
        if (b[l]>=b[r]){
            ans+=a[r]-a[l];
            while (l<r && b[l]>=b[r]) b[l]+=b[r--];
        } else{
            ans+=a[r]-a[l];
            while (l<r && b[l]<b[r]) b[r]+=b[l++];
        }
    }
    printf("%lld\n",ans);
    return 0;
}

总结

赛时通过AB,rk176,rating 1673 1765 ><

只是靠前两题的手速+一遍ac换来的rating(太菜了写不出C……。

继续加油辣!还差200+rating上黄 ><

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值