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] 表示覆蓋i次使得全部的點被覆蓋的方案數。

發現每個點被覆蓋的次數只會是1或2,並且兩個2之間1的個數必須是偶數,特別的,兩端的1個數位奇數,並且1和n的位置上只會是1。

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

注意這個 f[i] 求出的是所有長爲 i 的完全覆蓋的排列數,有可能是在 i 時已經完全覆蓋,需要減去 f[i1]

#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 ,那麼1肯定比n先訪問到。因爲如果要訪問n,一定會途徑n-1,經過n-1以後投票給正方向的人數只剩下了 Pn ,投票給負方向的人數 P1 ,而 P1Pn ,所以此時一定會走向1。

那麼我們進行這樣的操作:如果 P1Pn ,將 ans+=X[n]-X[1],然後 P[1]+=P[n],n--; 直到 P1<Pn

也就是說n左移過的那幾個點,都是由最後一次 1n 訪問到的。

當然如果是 P1<Pn ,情況是類似的。

然後再進行下一輪即可。直到【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上黃 ><

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章