2015年集训队作业

听说今年集训队作业是TC所以就从SRM699往前做好了。

SRM 699 250pts

按位处理。

#include <bits/stdc++.h>
using namespace std;
#define ll long long 
int n,a[41];
int cal(int x)
{
    int ret=0,sum=0,cnt=0;
    for(int i=0;i<n;i++)
        if(a[i]!=-1)
        {
            cnt++;
            sum+=(a[i]!=x);
        }
    int t=x^(sum&1);
    if(cnt==n&&t)return n+1;
    if(!cnt)return 0;
    return sum+t;
}
class OthersXor
{
    public:
    ll minSum(vector<int> v)
    {   
        ll ret=0;
        n=v.size();
        for(int i=0;i<30;i++)
        {
            for(int j=0;j<n;j++)
                a[j]= v[j]==-1 ? -1:v[j]>>i&1;
            int t=min(cal(0),cal(1));
            if(t>n)return -1;
            ret+=(ll)(1<<i)*t;
        }
        return ret;
    }
}cls;

SRM 699 500pts

考虑宽搜,如果S可以整除ai,把i推入队列,记录S到每个点的距离。
每次取队首的点,如果T可以整除对应的bi那么答案是S到这个点的距离+1
枚举没有入队过的j,如果lcm(bi,aj)<=n那么可以把j推入队列。

#include <bits/stdc++.h>
using namespace std;
#define N 1100
#define ll long long 
int vis[N],m,dis[N];
queue<int>q;
class FromToDivisible
{
    public:
    int shortest(int n,int S,int T,vector<int>a,vector<int>b)
    {
        m=a.size();
        for(int i=0;i<m;i++)
            if(S%a[i]==0)q.push(i),vis[i]=1;
        while(!q.empty())
        {
            int t=q.front();q.pop();
            if(T%b[t]==0)return dis[t]+1;
            for(int i=0;i<m;i++)
                if(!vis[i]&&(ll)a[i]*b[t]/__gcd(a[i],b[t])<=n)
                    q.push(i),vis[i]=1,dis[i]=dis[t]+1;
        }
        return -1;
    }
};

SRM 699 1000pts

#include <bits/stdc++.h>
using namespace std;
#define N 110
#define cl(x) memset(x,-0x3f,sizeof(x))
int n,a[N][N],ans,i,j,k;
int cal1(int x1,int y1,int x2,int y2)
{return a[x2][y2]-a[x1-1][y2]-a[x2][y1-1]+a[x1-1][y1-1];}
int cal0(int x1,int y1,int x2,int y2)
{return (x2-x1+1)*(y2-y1+1)-cal1(x1,y1,x2,y2);}
int cal(int x1,int y1,int x2,int y2)
{return cal0(x1,y1,x2,y2)-cal1(x1,y1,x2,y2);}
void upd(int &x,int y){x=max(x,y);}
int fit(int x){return x>=1&&x<=n;}
struct Type1
{
    int f[N][N][N];
    void solve()
    {
        cl(f);
        for(i=1;i<=n;i++)
            for(j=i;j<=n;j++)
                for(k=i;k<=n;k++)
                    upd(f[i][j][k],-cal(j-i+1,k-i+1,j,k));

        for(i=1;i<=n;i++)
            for(j=i;j<=n;j++)
                for(k=i;k<=n;k++)
                {
                    upd(f[i][j][k],f[i-1][j-1][k-1]);
                    upd(f[i][j][k],f[i-1][j-1][k]);
                    upd(f[i][j][k],f[i-1][j][k-1]);
                    upd(f[i][j][k],f[i-1][j][k]);
                }
        for(i=1;i<=n;i++)
            for(j=i;j<=n;j++)
                for(k=i;k<=n;k++)
                    upd(ans,cal(j-i+1,k-i+1,j,k)+f[i][j][k]);
    }
}type1;
struct Type2
{
    int L[N],R[N],U[N],D[N];
    void solve()
    {
        cl(L);cl(R);cl(U);cl(D);
        for(i=1;i<=n;i++)
            for(j=i;j<=n;j++)
                for(k=i;k<=n;k++)
                {
                    int t=cal(j-i+1,k-i+1,j,k);
                    upd(L[k],t);
                    upd(R[k-i+1],t);
                    upd(U[j],t);
                    upd(D[j-i+1],t);
                }
        for(i=1;i<=n;i++)
            upd(L[i],L[i-1]),upd(U[i],U[i-1]);
        for(i=n;i>=1;i--)
            upd(R[i],R[i+1]),upd(D[i],D[i+1]);
        for(i=1;i<=n;i++)
        {
            upd(ans,L[i]+R[i+1]);
            upd(ans,U[i]+D[i+1]);
        }
    }
}type2;
struct Type3
{
    int LU[N][N][N],LD[N][N][N],RU[N][N][N],RD[N][N][N];
    void solve()
    {
        cl(LU);cl(LD);cl(RU);cl(RD);
        for(i=1;i<=n;i++)
            for(j=i;j<=n;j++)
                for(k=i;k<=n;k++)
                {
                    int x1=j-i+1,y1=k-i+1,x2=j,y2=k;
                    int t=cal(x1,y1,x2,y2);
                    upd(LU[i][x1][y1],t);
                    upd(LD[i][x2][y1],t);
                    upd(RU[i][x1][y2],t);
                    upd(RD[i][x2][y2],t);
                }
        for(i=n;i>=1;i--)
            for(j=1;j<=n;j++)
                for(k=1;k<=n;k++)
                {
                    upd(LU[i][j][k],LU[i+1][j][k]);
                    upd(LD[i][j][k],LD[i+1][j][k]);
                    upd(RU[i][j][k],RU[i+1][j][k]);
                    upd(RD[i][j][k],RD[i+1][j][k]);
                }
        for(int x1=1;x1<=n;x1++)
            for(int y1=1;y1<=n;y1++)
                for(int x2=x1;x2<=n;x2++)
                    for(int y2=y1;y2<=n;y2++)
                    {
                        int l=max(x2-x1+1,y2-y1+1);
                        int t=cal(x1,y1,x2,y2);
                        upd(ans,RD[l][x2][y2]+LU[l][x1][y1]-t*2);
                        upd(ans,LD[l][x2][y1]+RU[l][x1][y2]-t*2);
                    }
    }
}type3;
struct Type4
{
    int L[N][N][N],R[N][N][N],U[N][N][N],D[N][N][N];
    void solve()
    {
        cl(L);cl(R);cl(U);cl(D);
        for(i=1;i<=n;i++)
            for(j=i;j<=n;j++)
                for(k=i;k<=n;k++)
                {
                    int x1=j-i+1,y1=k-i+1,x2=j,y2=k;
                    int t=cal(x1,y1,x2,y2);
                    upd(L[y2][x1][x2],t);
                    upd(R[y1][x1][x2],t);
                    upd(U[x2][y1][y2],t);
                    upd(D[x1][y1][y2],t);
                }
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
                for(k=n;k>=j;k--)
                {
                    upd(L[i][j][k],L[i][j-1][k]);
                    upd(L[i][j][k],L[i][j][k+1]);

                    upd(R[i][j][k],R[i][j-1][k]);
                    upd(R[i][j][k],R[i][j][k+1]);

                    upd(U[i][j][k],U[i][j-1][k]);
                    upd(U[i][j][k],U[i][j][k+1]);

                    upd(D[i][j][k],D[i][j-1][k]);
                    upd(D[i][j][k],D[i][j][k+1]);   
                }
        for(int x1=1;x1<=n;x1++)
            for(int y1=1;y1<=n;y1++)
                for(int x2=x1;x2<=n;x2++)
                    for(int y2=y1;y2<=n;y2++)
                    {
                        int t=cal(x1,y1,x2,y2);
                        if(x2-x1>=y2-y1)
                        {
                            if(fit(y1-x1+x2))
                                upd(ans,L[y2][x1][x2]+cal(x1,y1,x2,y1-x1+x2)-t*2);
                            if(fit(y2-x2+x1))   
                                upd(ans,R[y1][x1][x2]+cal(x1,y2-x2+x1,x2,y2)-t*2);
                        }
                        if(y2-y1>=x2-x1)
                        {
                            if(fit(x1+y2-y1))
                                upd(ans,U[x2][y1][y2]+cal(x1,y1,x1+y2-y1,y2)-t*2);
                            if(fit(x2-y2+y1))
                                upd(ans,D[x1][y1][y2]+cal(x2-y2+y1,y1,x2,y2)-t*2);
                        }
                    }
    }
}type4;
class TwoSquares
{
public:
    int maxOnes(vector<string> s)
    {
        n=s.size();
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
                a[i][j]=(s[i-1][j-1]=='1');
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
                a[i][j]=a[i][j]+a[i-1][j]+a[i][j-1]-a[i-1][j-1];

        for(i=1;i<=n;i++)
            for(j=i;j<=n;j++)
                for(k=i;k<=n;k++)
                    upd(ans,cal(j-i+1,k-i+1,j,k));

        type1.solve();
        type2.solve();
        type3.solve();
        type4.solve();

        return a[n][n]+ans;
    }
}cls;

SRM 698 250pts

#include <bits/stdc++.h>
using namespace std;
int n,ans;
char s1[51];
int f[51][51];
int cal(int x)
{
    memset(f,0x3f,sizeof(f));
    f[0][x]=0;
    for(int i=0;i<=x;i++)
        for(int j=x;j<=n;j++)
        {
            if(i)f[i][j]=min(f[i][j],f[i-1][j]+1);
            if(j!=x)f[i][j]=min(f[i][j],f[i][j-1]+1);
            if(i&&j!=x)f[i][j]=min(f[i][j],f[i-1][j-1]+(s1[i]!=s1[j]));
        }
    return f[x][n];
}
class RepeatString
{
public:
    int minimalModify(string s)
    {
        n=s.size();
        for(int i=0;i<n;i++)s1[i+1]=s[i];
        ans=n;
        for(int i=1;i<=n;i++)
            ans=min(ans,cal(i));
        return ans;
    }
};

SRM 698 500pts

#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define ll long long
#define N 110
int n,ans;
int jc[N],njc[N];
int qpow(int x,int y)
{
    int ret=1;
    while(y)
    {
        if(y&1)ret=(ll)ret*x%mod;
        x=(ll)x*x%mod;y>>=1;
    }
    return ret;
}
int C(int x,int y)
{return (ll)jc[x]*njc[y]%mod*njc[x-y]%mod;}
class IntersectingConvexHull
{
public:
    int count(vector<int>X,vector<int>Y)
    {
        n=X.size();jc[0]=njc[0]=1;
        for(int i=1;i<=n;i++)
            jc[i]=(ll)jc[i-1]*i%mod;

        njc[n]=qpow(jc[n],mod-2);
        for(int i=n-1;i>=1;i--)
            njc[i]=(ll)njc[i+1]*(i+1)%mod;

        for(int i=3;i<=n;i++)
            for(int j=3;i+j<=n;j++)
                (ans+=(ll)C(n,i)*C(n-i,j)%mod)%=mod;

        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                if(i!=j)
                {
                    int l=0,r=0;
                    for(int k=0;k<n;k++)
                        if(k!=i&&k!=j)
                        {
                            ll t=(ll)(X[j]-X[i])*(Y[k]-Y[i])-(ll)(X[k]-X[i])*(Y[j]-Y[i]);
                            if(t<0)l++;else r++;
                        }
                        ans-=(ll)(qpow(2,l)-l-1)*(qpow(2,r)-r-1)%mod;
                        ans=(ans%mod+mod)%mod;
                }
        return ans;
    }
};

SRM 698 1000pts

#include <bits/stdc++.h>
using namespace std;
#define N 4100
#define M 110000
int n,w,h,cnt,tot,top;
int p[110][8][2];
int head[N],nex[M],to[M];
int dir[8][2]={{-1,-1},{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},};
int mark[N],fin[N],st[N];
char ans[N],s1[4]="CL?";
vector<int>X1,Y1;
vector<string>ss;
void add(int x,int y)
{
    tot++;
    nex[tot]=head[x];head[x]=tot;
    to[tot]=y;
}
void ade(int x,int y)
{add(x,y);add(y^1,x^1);}
void dfs(int x)
{
    mark[x]=1;
    for(int i=head[x];i;i=nex[i])
        if(!mark[to[i]])dfs(to[i]);
}
int check(int x,int y)
{
    memset(mark,0,sizeof(mark));
    for(int i=0;i<4;i++)
        dfs(p[x][(y+i)&7][1]);
    for(int i=2;i<=cnt;i+=2)
        if(mark[i]&&mark[i^1])return 0;
    return 1;
}
int ch(int pos,int v)
{
    pos--;
    int x=X1[pos]+dir[v][0];
    int y=Y1[pos]+dir[v][1];
    if(x<0||x>=h||y<0||y>=w||ss[x][y]=='#')return 0;
    return 1;
}
pair<int,int> get(int pos,int v)
{return make_pair(X1[pos-1]+dir[v][0],Y1[pos-1]+dir[v][1]);}
class Puzzle58
{
public:
    string getAnswer(vector<string>s,vector<int>X,vector<int>Y)
    {
        X1=X;Y1=Y;ss=s;
        h=s.size();w=s[0].size();n=X.size();
        cnt=1;
        for(int i=1;i<=n;i++)
            for(int j=0;j<8;j++)
                for(int k=0;k<=1;k++)p[i][j][k]=++cnt;

        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<4;j++)
            {
                ade(p[i][j][1],p[i][(j+4)&7][0]);
                ade(p[i][j][0],p[i][(j+4)&7][1]);
            }
            for(int j=0;j<8;j++)
                if(!ch(i,j)||!ch(i,(j+1)&7))
                    add(p[i][j][1],p[i][j][0]);
        }

        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if(i!=j)
                {
                    if(X[i]==X[j]&&Y[i]==Y[j])
                        return string("Impossible");
                    for(int k=0;k<8;k++)
                        for(int t=0;t<8;t++)
                            if(get(i,k)==get(j,t)||get(i,(k+1)&7)==get(j,t)||
                            get(i,k)==get(j,(t+1)&7)||get(i,(k+1)&7)==get(j,(t+1)&7))
                                ade(p[i][k][1],p[j][t][0]);
                }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<8;j+=2)
                if(check(i,j)){fin[i]|=1;break;}
            for(int j=0;j<8;j+=2)
                if(check(i,j)){fin[i]|=2;break;}
            if(!fin[i])return string("Impossible");     
            ans[i-1]=s1[fin[i]-1];
        }
        ans[n]='\0';
        return string(ans);
    }
};

SRM 548 250pts

#include <bits/stdc++.h>
using namespace std;
int n;
int a[61],b[61];
int check(int x)
{   
    for(int i=1;i<=n;i++)b[i]=a[i];
    b[n]+=x;
    for(int i=n-1;i>=1;i--)
    {
        if(b[i+1]<=b[i]-x||b[i+1]<=1)return 0;
        b[i]=min(b[i]+x,b[i+1]-1);
    }
    return 1;
}
class KingdomAndTrees
{
public:
    int minLevel(vector<int>b)
    {
        n=b.size();
        for(int i=1;i<=n;i++)a[i]=b[i-1];
        int l=0,r=1e9;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(check(mid))r=mid-1;
            else l=mid+1;
        }
        return l;
    }
};

SRM 548 450pts

#include <bits/stdc++.h>
using namespace std;
bool f[61][61][2600];
int n,cnt,num[61],sum,ret;
class KingdomAndDice
{
public:
    double newFairness(vector<int>a,vector<int>b,int v)
    {
        sort(a.begin(),a.end());
        sort(b.begin(),b.end());
        n=a.size();num[0]=n+1;
        for(int i=1;i<n;i++)num[i]=min(b[i]-b[i-1]-1,n+1);
        num[n]=min(v-b[n-1],n+1);
        for(int i=0,j;i<n;i++)
        {
            if(a[i]==0)cnt++;
            else 
            {
                for(j=0;j<n;j++)
                    if(b[j]>a[i])break;
                num[j]--;sum+=j;
            }
        }
        ret=sum*2;
        for(int i=0;i<=cnt;i++)f[0][i][0]=1;
        for(int i=1;i<=n;i++)
            for(int j=0;j<=cnt;j++)
                for(int t=0;t<=j&&t<=num[i];t++)
                {
                    int t1=t*i,t2=j*i;
                    for(int k=t1;k<=t2;k++)
                        f[i][j][k]|=f[i-1][j-t][k-t1];
                }
        for(int i=0;i<=n*cnt;i++)
            if(f[n][cnt][i])
            {
                int t=(i+sum)*2;
                int t1=abs(t-n*n),t2=abs(ret-n*n);
                if(t2>t1||(t2==t1&&t<ret))
                    ret=t;
            }
        return (double)ret/(n*n*2);
    }
}cls;

SRM 548 1000pts

#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define ll long long 
int c[61][61],C[3100][61],f[61][61],ans;
class KingdomAndCities
{
public:
    int howMany(int n,int m,int K)
    {
        for(int i=0;i<=2500;i++)C[i][0]=1;
        for(int i=1;i<=2500;i++)
            for(int j=1;j<=50;j++)
                C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;

        f[1][0]=1;
        for(int i=2;i<=n;i++)
            for(int j=1;j<=K;j++)
            {
                f[i][j]=C[i*(i-1)/2][j];
                for(int k=1;k<=i-1;k++)
                    for(int t=0;t<=j;t++)
                        f[i][j]=(f[i][j]-(ll)f[k][t]*C[(i-k)*(i-k-1)/2][j-t]%mod
                        *C[i-1][k-1]%mod+mod)%mod;
            }
        if(!m)return f[n][K];
        if(m==1)
        {
            ans=(ll)f[n-1][K-2]*((n-1)*(n-2)/2)%mod;
            for(int i=1;i<n-1;i++)
                for(int j=0;j<=K-2;j++)
                {
                    if(n-i-1>i)continue;
                    ans=(ans+(ll)(i!=n-i-1 ? C[n-1][i]:C[n-2][i])
                    *f[i][j]%mod*f[n-i-1][K-j-2]%mod*i%mod*(n-i-1)%mod)%mod;
                }
            return ans;
        }
        if(K<4)return 0;
        ans=(ll)f[n-2][K-4]*((n-2)*(n-3)/2)%mod*((n-2)*(n-3)/2)%mod;
        ans=(ans+(ll)f[n-2][K-3]*((n-2)*(n-2)))%mod;
        for(int i=1;i<n-2;i++)
            for(int j=0;j<=K-4;j++)
            {
                if(n-i-2>i)continue;
                ans=(ans+(ll)(i!=n-i-2 ? C[n-2][i]:C[n-3][i])
                *f[i][j]%mod*f[n-i-2][K-j-4]%mod*
                (i*(n-i-2)*i*(n-i-2)+(i*(i-1)+(n-i-2)*(n-i-3))*i*(n-i-2))%mod)%mod;
            }
        for(int i=1;i<n-2;i++)
            for(int j=0;j<=K-3;j++)
            {
                if(n-i-2>i)continue;
                ans=(ans+(ll)(i!=n-i-2 ? C[n-2][i]:C[n-3][i])
                *f[i][j]%mod*f[n-i-2][K-j-3]%mod*(i*(n-i-2)*2)%mod)%mod;
            }
        for(int i=1;i<n-2;i++)
            for(int j=0;j<=K-4;j++)
                for(int k=1;k+i<n-2;k++)
                    for(int t=0;t+j<=K-4;t++)
                    {
                        ans=(ans+(ll)C[n-2][n-i-k-2]*C[i+k][i]%mod
                        *f[i][j]%mod*f[k][t]%mod*f[n-i-k-2][K-j-t-4]%mod*
                        (i*(n-i-k-2)*(n-i-k-2)*k)%mod)%mod;
                    }
        return ans;
    }
};

SRM 587 250pts

#include <bits/stdc++.h>
using namespace std;
#define N 81000
double a[N],sum[N],ans;
class JumpFurther
{
public:
    int furthest(int n,int m)
    {
        int sum=0,flag=1;
        for(int i=1;i<=n;i++)
        {
            sum+=i;
            if(sum==m)flag=0;
        }
        sum=flag;
        for(int i=2;i<=n;i++)
            sum+=i;
        return sum;
    }
};

SRM 587 550pts

#include <bits/stdc++.h>
using namespace std;
#define N 81000
double a[N],sum[N],ans;
class TriangleXor
{
public:
    int theArea(int n)
    {
        for(int i=1;i<=n;i++)
        {
            a[i]=(double)i/(n+i)-(double)(i-1)/(n+i-1);
            if(!(i&1))a[i]=-a[i];
        }
        for(int i=1;i<=n;i++)sum[i]=sum[i-1]+a[i];
        for(int i=n;i>=1;i--)ans+=sum[i]*n/2;
        for(int i=1;i<=n;i+=2)ans+=a[i]*n/2;
        if(!(n&1))ans+=(double)n/4;
        return (int)ans;
    }
};

SRM 587 900pts

#include <bits/stdc++.h>
using namespace std;
#define N 61
int w,h;
int a[N][N],bel[N],val[N],ma[N][N];
int pos[N][N];
vector<string>ret;
int dfs(int x,int v,int tp)
{
    if(bel[x])return val[x]==(tp&1);
    bel[x]=v;val[x]=tp&1;
    for(int i=1;i<=h;i++)
        if(ma[x][i]!=-1)
            if(!dfs(i,v,tp+ma[x][i]))
                return 0;
    return 1;
}
void merge(int x,int tp)
{
    for(int i=1;i<=h;i++)
        if(bel[i]==x)val[i]^=tp;
    for(int i=1;i<=w;i++)
        if(pos[x][i]!=-1)
            pos[x][i]^=tp,pos[1][i]=pos[x][i];

    for(int i=1;i<=h;i++)
        if(bel[i]==1)
        {
            for(int j=1;j<=w;j++)
                if(pos[x][j]!=-1)
                    a[i][j]=pos[x][j]^val[i];
        }
    for(int i=1;i<=h;i++)
        if(bel[i]==x)
        {
            bel[i]=1;
            for(int j=1;j<=w;j++)
                if(pos[1][j]!=-1)
                    a[i][j]=pos[1][j]^val[i];
        }
}
class ThreeColorability
{
public:
    vector<string> lexSmallest(vector<string>s)
    {
        memset(ma,-1,sizeof(ma));
        memset(pos,-1,sizeof(pos));
        h=s.size();w=s[0].size();
        for(int i=1;i<=h;i++)
            for(int j=1;j<=w;j++)
            {
                char c=s[i-1][j-1];
                a[i][j]=(c=='?' ? -1:(c=='N' ? 0:1));
            }
        for(int i=1;i<=h;i++)
            for(int j=i+1;j<=h;j++)
                for(int k=1;k<=w;k++)
                    if(a[i][k]!=-1&&a[j][k]!=-1)
                    {
                        int t=(a[i][k]!=a[j][k]);
                        if(ma[i][j]!=-1&&ma[i][j]!=t)return ret;
                        ma[i][j]=ma[j][i]=t;
                    }
        for(int i=1;i<=h;i++)
            if(!bel[i])
            {
                if(!dfs(i,i,0))return ret;
                for(int j=1;j<=h;j++)
                    if(bel[j]==i)
                        for(int k=1;k<=w;k++)
                            if(a[j][k]!=-1)pos[i][k]=(a[j][k]^val[j]);

                for(int j=1;j<=h;j++)
                    if(bel[j]==i)
                        for(int k=1;k<=w;k++)
                            if(pos[i][k]!=-1)
                            {
                                int t=pos[i][k]^val[j];
                                if(a[j][k]!=-1&&a[j][k]!=t)return ret;
                                a[j][k]=t;
                            }
            }
        for(int i=1;i<=w;i++)
            if(pos[1][i]==-1)
            {
                a[1][i]=0;pos[1][i]=0;
                for(int j=2;j<=h;j++)
                    if(bel[j]==1)a[j][i]=val[j];
                for(int j=2,t;j<=h;j++)
                    if((t=bel[j])!=1&&pos[t][i]!=-1)
                        merge(t,a[j][i]!=a[1][i]);
            }
        for(int i=2;i<=h;i++)
            if(a[i][1]==-1)
            {
                int t=a[1][1];
                for(int j=1;j<=w;j++)
                    a[i][j]=a[1][j]^t;
            }
        ret.resize(h);
        for(int i=1;i<=h;i++)
            for(int j=1;j<=w;j++)
                ret[i-1]+=(a[i][j] ? "Z":"N");
        return ret;
    }
};

SRM 556 250pts

#include <bits/stdc++.h>
using namespace std;
#define PA pair<int,int> 
#define M 1100
#define N 61
int f[N][M],n,ans;
queue<PA>q;
class XorTravelingSalesman
{
public:
    int maxProfit(vector<int>v,vector<string>a)
    {       
        n=v.size();
        f[0][v[0]]=1;ans=v[0];
        q.push(make_pair(0,v[0]));
        while(!q.empty())
        {
            PA t=q.front();q.pop();
            int x=t.first,y=t.second;
            for(int i=0;i<n;i++)
                if(a[x][i]=='Y')
                {
                    if(!f[i][y^v[i]])
                    {
                        ans=max(ans,y^v[i]);
                        f[i][y^v[i]]=1;
                        q.push(make_pair(i,y^v[i]));
                    }
                }
        }
        return ans;
    }
};

SRM 556 500pts

#include <bits/stdc++.h>
using namespace std;
int n;
string dig,org,ret;
string f[61][61][3][3];
bool vis[61][61][3][3];
string cal(int l,int r,int v1,int v2)
{   
    if(vis[l][r][v1][v2])
        return f[l][r][v1][v2];
    if(l+r==n)
    {
        if(v1==0||(v1==1&&v2==0))return "#";
        return "";
    }
    f[l][r][v1][v2]="#";
    vis[l][r][v1][v2]=1;

    int v=v1;
    if(v1==1)
    {
        if(dig[l+r]<org[l])v=0;
        else if(dig[l+r]>org[l])v=2;
    }
    string t1=cal(l+1,r,v,v2);
    if(t1!="#")f[l][r][v1][v2]=dig[l+r]+t1;

    v=v2;
    if(dig[l+r]>org[n-r-1])v=2;
    else if(dig[l+r]<org[n-r-1])v=0;
    t1=cal(l,r+1,v1,v);
    if(t1!="#")
    {
        if(f[l][r][v1][v2]=="#")f[l][r][v1][v2]=t1+dig[l+r];
        else f[l][r][v1][v2]=min(f[l][r][v1][v2],t1+dig[l+r]);
    }
    return f[l][r][v1][v2];
}
class LeftRightDigitsGame2
{
public:
    string minNumber(string s1,string s2)
    {       
        n=s1.size();
        org=s2;dig="";
        for(int i=0;i<n;i++)dig=s1[i]+dig;
        ret=cal(0,0,1,1);
        if(ret=="#")return "";
        return ret;
    }
};

SRM 556 1000pts

#include <bits/stdc++.h>
using namespace std;
#define N 61
#define M 11000
const int inf=1e9;
int tot,S,T,n;
int a[N][N],head[N],nex[M],to[M],val[M],deep[N];
queue<int>q;
void add(int x,int y,int z)
{
    tot++;
    nex[tot]=head[x];head[x]=tot;
    to[tot]=y;val[tot]=z;
}
void ade(int x,int y,int z)
{add(x,y,z);add(y,x,0);}
int bfs()
{
    while(!q.empty())q.pop();
    memset(deep,-1,sizeof(deep));
    deep[S]=0;q.push(S);
    while(!q.empty())
    {
        int tmp=q.front();q.pop();
        for(int i=head[tmp];i;i=nex[i])
            if(val[i]&&deep[to[i]]==-1)
            {
                deep[to[i]]=deep[tmp]+1;
                q.push(to[i]);
                if(to[i]==T)return 1;
            }
    }
    return 0;
}
int dfs(int x,int mv)
{
    if(x==T)return mv;
    int tmp=0;
    for(int i=head[x];i;i=nex[i])
        if(deep[to[i]]==deep[x]+1&&val[i])
        {
            int t=dfs(to[i],min(mv-tmp,val[i]));
            tmp+=t;val[i]-=t;
            val[i^1]+=t;
            if(tmp==mv)break;
        }
    return tmp;
}
int cal(int x1,int x2,int y1,int y2,int an,int bn)
{
    memset(head,0,sizeof(head));tot=1;
    for(int i=0;i<n;i++)
        for(int j=i+1;j<n;j++)
            if(a[i][j])add(i,j,a[i][j]),add(j,i,a[i][j]);
    S=n;T=n+1;
    ade(S,x1,an*2);ade(S,x2,bn*2);
    ade(y1,T,an*2);ade(y2,T,bn*2);

    int ret=0;
    while(bfs())
        ret+=dfs(S,inf);
    return ret;
}
class OldBridges
{
public:
    string isPossible(vector<string>s,int a1,int a2,int an,int b1,int b2,int bn)
    {
        n=s.size();
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                a[i][j]=s[i][j]=='X' ? 0:(s[i][j]=='O' ? 2:inf);
        if(cal(a1,b1,a2,b2,an,bn)<(an+bn)*2)return "No";
        if(cal(a1,b2,a2,b1,an,bn)<(an+bn)*2)return "No";
        return "Yes";
    }
};

SRM 586 250pts

#include <bits/stdc++.h>
using namespace std;
int a[61],b[61],n,ans;
void cal(int x)
{
    int ret=0;
    for(int i=1;i<n;i++)
    {
        if(b[i]>b[i+1])
            {if(b[i]*2>=x&&b[i+1]*2+1<=x)ret++;}
        else
            {if(b[i]*2<=x&&b[i+1]*2-1>=x)ret++;}
    }
    if(b[n]*2==x)ret++;
    ans=max(ans,ret);
}
class PiecewiseLinearFunction
{
public:
    int maximumSolutions(vector<int>v)
    {
        n=v.size();
        for(int i=0;i<n;i++)
            a[i+1]=b[i+1]=v[i];
        for(int i=1;i<n;i++)
            if(b[i]==b[i+1])return -1;
        sort(a+1,a+1+n);
        for(int i=1;i<n;i++)
            cal(a[i]*2),cal(a[i]+a[i+1]);
        cal(a[n]*2);
        return ans;
    }
};

SRM 586 500pts

#include <bits/stdc++.h>
using namespace std;
#define M 2100
int tot,n,m;
int a[31][51],num[51],l[51],r[51];
int head[51],nex[M],v1[M],v2[M],to[M],inq[51];
string s,ret;
queue<int>q;
const int inf=1e9;
void add(int x,int y,int t1,int t2)
{
    tot++;
    nex[tot]=head[x];head[x]=tot;
    v1[tot]=t1;v2[tot]=t2;to[tot]=y;
}
class History
{
public:
    string verifyClaims(vector<string>s1,vector<string>s2,vector<string>s3)
    {       
        n=s1.size();
        for(int i=0,now=0;i<n;i++)
        {
            for(int j=0;j<s1[i].size();j++)
            {
                if(isdigit(s1[i][j]))now=now*10+s1[i][j]-'0';
                else a[i][num[i]++]=now,now=0;
            }
            a[i][num[i]++]=now;now=0;
        }
        s="";
        for(int i=0;i<s2.size();i++)s=s+s2[i];
        for(int i=0;i<s.size();i++)
            if(isupper(s[i]))
            {
                int c1=s[i]-'A',c2,t1=0,t2=0;
                for(i++;isdigit(s[i]);i++)t1=t1*10+s[i]-'0';
                c2=s[++i]-'A';
                for(i++;isdigit(s[i]);i++)t2=t2*10+s[i]-'0';
                add(c1,c2,t1,t2);
                add(c2,c1,t2,t1);
            }
        m=s3.size();ret="";
        for(int i=0;i<m;i++)
        {
            int c1=s3[i][0]-'A',c2,t1=0,t2=0,now=1;
            for(;isdigit(s3[i][now]);now++)t1=t1*10+s3[i][now]-'0';
            c2=s3[i][++now]-'A';
            for(now++;isdigit(s3[i][now]);now++)t2=t2*10+s3[i][now]-'0';

            for(int j=0;j<n;j++)
                l[j]=-inf,r[j]=inf;
            l[c1]=r[c1]=0;q.push(c1);
            while(!q.empty())
            {
                int tmp=q.front();q.pop();
                inq[tmp]=0;
                for(int j=head[tmp];j;j=nex[j])
                {
                    int flag=0,t=0;
                    if(r[t=to[j]]+a[t][v2[j]]>r[tmp]+a[tmp][v1[j]+1]-1)
                        flag=1,r[t]=r[tmp]+a[tmp][v1[j]+1]-1-a[t][v2[j]];
                    if(l[t]+a[t][v2[j]+1]-1<l[tmp]+a[tmp][v1[j]])
                        flag=1,l[t]=l[tmp]+a[tmp][v1[j]]+1-a[t][v2[j]+1];
                    if(flag&&!inq[t])
                        inq[t]=1,q.push(t);
                }
            }
            int l1=l[c1]+a[c1][t1],r1=r[c1]+a[c1][t1+1]-1,
            l2=l[c2]+a[c2][t2],r2=r[c2]+a[c2][t2+1]-1;
            if(r2<l1||r1<l2)ret+="N";
            else ret+="Y";
        }
        return ret;
    }
};

SRM586 1000pts

#include <bits/stdc++.h>
using namespace std;
int f[51][27][27],b[51];
int n,inf,ans;
void upd(int &x,int y){x=min(x,y);}
int cal(int x){return x*(x+1)/2;}
class StringWeight
{
public:
    int getMinimum(vector<int> a)
    {
        memset(f,0x3f,sizeof(f));inf=f[0][0][0];
        n=a.size();f[0][0][0]=0;
        for(int i=0;i<n;i++)b[i]=min(a[i],26);
        for(int i=0;i<n;i++)
            for(int j=0;j+b[i]<=26;j++)
                for(int k=0;j+k<=26;k++)
                {
                    if(f[i][j][k]==inf)continue;
                    for(int t=0;t<=k&&t<=a[i];t++)
                        for(int w=0;w<=26-j-k&&w<=b[i]-t;w++)
                            for(int r=0;r<=26-j-k&&t+r+w<=b[i];r++)
                            {
                                if(k-t<b[i]-t-w-r)continue;
                                int t1=f[i][j][k]+(k-t)*a[i]+cal(t-1)+cal(w);
                                if(a[i]>26&&t+w+r==26)t1+=a[i]-26;
                                upd(f[i+1][j+t+r][k-t+w],t1);
                            }
                }
        ans=inf;
        for(int i=0;i<=26;i++)
            ans=min(ans,f[n][i][0]);
        return ans;
    }
};

SRM566 div2 250pts

#include <bits/stdc++.h>
using namespace std;
int n,m;
class PenguinTiles
{
public:
    int minMoves(vector<string> s)
    {
        n=s.size();m=s[0].size();
        if(s[n-1][m-1]=='.')return 0;
        for(int i=0;i<n;i++)
            if(s[i][m-1]=='.')return 1;
        for(int i=0;i<m;i++)
            if(s[n-1][i]=='.')return 1;
        return 2;
    }
};

SRM566 div2 500pts

#include <bits/stdc++.h>
using namespace std;
int f[61][61],n;
class PenguinPals
{
public:
    int findMaximumMatching(string s)
    {
        n=s.size();
        for(int i=1;i<=n;i++)
            for(int j=1;j+i<=n;j++)
            {
                f[j][j+i]=max(f[j+1][j+i],f[j][j+i-1]);
                if(s[j-1]==s[j+i-1])
                    f[j][j+i]=max(f[j][j+i],f[j+1][j+i-1]+1);
                for(int k=j+1;k<=j+i;k++)
                    f[j][j+i]=max(f[j][j+i],f[j][k-1]+f[k][j+i]);
            }
        return f[1][n];
    }
};

SRM566 div2 1000pts

#include <bits/stdc++.h>
using namespace std;
const double PI=acos(-1);
struct poi
{
    double x,y;
    poi(){}
    poi(double x,double y):x(x),y(y){}
    friend double operator ^ (const poi &r1,const poi &r2)
    {return r1.x*r2.y-r2.x*r1.y;};
    friend poi operator  - (const poi &r1,const poi &r2)
    {return poi(r1.x-r2.x,r1.y-r2.y);};
}a[310],c[310];
int m;
int v[310][310];
double f[310],ans;
double dis(poi p1)
{return sqrt(p1.x*p1.x+p1.y*p1.y);}
double cal(int x,int y,int z)
{
    double d1=dis(c[x]-c[y]),d2=dis(c[y]-c[z]),d3=dis(c[z]-c[x]);
    double p=(d1+d2+d3)/2;
    return sqrt(p*(p-d1)*(p-d2)*(p-d3));
}
class FencingPenguinsEasy
{
public:
    double calculateMinArea(int n,int r,vector<int>X,vector<int>Y)
    {
        for(int i=0;i<n;i++)
        {
            c[i].y=r*sin(2*PI*i/n);
            c[i].x=r*cos(2*PI*i/n);
        }
        m=X.size();
        for(int i=1;i<=m;i++)
            a[i].x=X[i-1],a[i].y=Y[i-1];

        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                if(i!=j)
                {
                    v[i][j]=1;
                    for(int k=1;k<=m;k++)
                        if(((a[k]-c[i])^(c[j]-c[i]))>0)v[i][j]=0;
                }
        for(int i=0;i<n;i++)
            if(!v[i][(i+1)%n])return -1;
        ans=1e100;
        for(int now=0;now<n;now++)
        {
            for(int i=1;i<n;i++)f[i]=1e100;
            f[0]=0;
            for(int i=1;i<n;i++)
            {
                if(v[now][(now+i)%n])f[i]=0;
                else for(int j=i-1;j>=1;j--)
                    if(v[(now+j)%n][(now+i)%n])
                        f[i]=min(f[i],f[j]+cal((now+j)%n,(now+i)%n,now));
            }
            for(int i=n-1;i>1;i--)
                if(v[(now+i)%n][now])ans=min(ans,f[i]);
        }
        return ans;
    }
};

SRM566 div1 250pts

#include <bits/stdc++.h>
using namespace std;
#define ll long long
int cnt[61],m,a[61][61];
ll ans;
ll bir[61];
class PenguinSledding
{
public:
    ll countDesigns(int n,vector<int>X,vector<int>Y)
    {   
        m=X.size();ans=m+1;
        bir[0]=1;
        for(int i=1;i<=m;i++)
            bir[i]=bir[i-1]<<1;

        for(int i=0;i<m;i++)
        {
            cnt[X[i]]++,cnt[Y[i]]++;
            a[X[i]][Y[i]]=a[Y[i]][X[i]]=1;
        }
        for(int i=1;i<=n;i++)
            ans=ans+bir[cnt[i]]-cnt[i]-1;

        for(int i=1;i<=n;i++)
            for(int j=i+1;j<=n;j++)
                for(int k=j+1;k<=n;k++)
                    if(a[i][j]&&a[j][k]&&a[k][i])
                        ans++;
        return ans;
    }   
}cls;

SRM566 div1 500pts

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 1000000007
int f[2][410];
int n1;
struct matrix
{
    int w[410];
    friend matrix operator * (const matrix &r1,const matrix &r2)
    {
        matrix ret;
        memset(&ret,0,sizeof(ret));
        for(int i=0;i<n1;i++)
            for(int j=0;j<n1;j++)
                (ret.w[(i+j)%n1]+=(ll)r1.w[i]*r2.w[j]%mod)%=mod;
        return ret;
    };
}fin;
matrix qpow(matrix x,ll y)
{
    matrix ret;
    memset(&ret,0,sizeof(ret));
    ret.w[0]=1;
    while(y)
    {
        if(y&1)ret=ret*x;
        x=x*x;y>>=1;
    }
    return ret;
}
class PenguinEmperor
{
public:
    int countJourneys(int n,ll m)
    {
        n1=n;f[0][0]=1;
        for(int i=1;i<=n;i++)
        {
            memset(f[i&1],0,sizeof(f[i&1]));
            for(int j=0;j<n;j++)
            {
                (f[i&1][(j+i)%n]+=f[~i&1][j])%=mod;
                if((j+i)%n!=(j-i+n)%n)
                    (f[i&1][(j-i+n)%n]+=f[~i&1][j])%=mod;
            }
        }
        for(int i=0;i<n;i++)
            fin.w[i]=f[n&1][i];
        fin=qpow(fin,m/n);m%=n;

        for(int i=0;i<n;i++)
            f[0][i]=fin.w[i];
        for(int i=1;i<=m;i++)
        {
            memset(f[i&1],0,sizeof(f[i&1]));
            for(int j=0;j<n;j++)
            {
                (f[i&1][(j+i)%n]+=f[~i&1][j])%=mod;
                if((j+i)%n!=(j-i+n)%n)
                    (f[i&1][(j-i+n)%n]+=f[~i&1][j])%=mod;
            }
        }       
        return f[m&1][0];
    }
};

SRM566 div1 1000pts

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 100007
#define N 310
const double PI=acos(-1);
int m;
struct poi
{
    double x,y;
    poi(){}
    poi(double x,double y):x(x),y(y){}
    friend double operator ^ (const poi &p1,const poi &p2)
    {return p1.x*p2.y-p2.x*p1.y;};
    friend poi operator - (const poi &p1,const poi &p2)
    {return poi(p1.x-p2.x,p1.y-p2.y);};
}c[N],a[N];
int col[N],h[N][N][2],f[N][N],g[N][N],vil[N][N];
ll lp[N][N],lc[N][N];
class FencingPenguins
{
public:
    int countWays(int n,int r,vector<int>X,vector<int>Y,string color)
    {   
        for(int i=0;i<n;i++)
        {
            c[i].y=sin(2*PI*i/n)*r;
            c[i].x=cos(2*PI*i/n)*r;
        }
        m=X.size();
        for(int i=0;i<m;i++)a[i]=poi(X[i],Y[i]);
        for(int i=0;i<m;i++)col[i]=color[i]-'A';

        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                if(i!=j)
                {
                    for(int k=0;k<m;k++)
                        if(((a[k]-c[i])^(c[j]-c[i]))<=0)
                        {
                            lp[i][j]|=1ll<<k;
                            lc[i][j]|=1ll<<col[k];
                        }
                }
        if(lp[0][n-1])return 0;
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                if(i!=j)
                    vil[i][j]=lc[i][j]&lc[j][i] ? 0:1;

        for(int i=0;i<n;i++)h[i][i][1]=1;
        for(int i=1;i<n;i++)
            for(int l=0;l+i<n;l++)
            {
                int sum=0,r=l+i;
                for(int j=0;j<=1;j++)
                {   
                    sum=0;
                    for(int nl=l+1;nl<=r;nl++)
                        if(vil[l][nl])
                        {
                            ll t=lp[l][nl]&lp[nl][r]&lp[r][l];
                            int type=t ? 1:j;
                            if(!lp[nl][l])
                                sum+=h[nl][r][type];
                            else if(l+2<nl-1&&!(lp[nl][l]&lp[l+1][nl-1]))
                                sum+=(ll)h[nl][r][type]*f[l+1][nl-1]%mod;
                        }
                    h[l][r][j]=sum%mod;
                }
                sum=0;
                for(int nl=l+2;nl<=r;nl++)
                    if(vil[l][nl])
                    {
                        ll t=lp[r][l]&lp[l][nl];
                        if(!t)sum+=h[l][nl][0];
                        else if(nl+2<r&&!(t&lp[nl+1][r]))
                            sum+=(ll)h[l][nl][0]*f[nl+1][r]%mod;
                    }
                g[l][r]=sum%mod;

                sum=0;
                for(int nl=l;nl<r-1;nl++)
                    if(!(lp[nl][r]&lp[r][l]))
                        sum+=g[nl][r];
                f[l][r]=sum%mod;
            }
        return f[0][n-1];
    }
}cls;

SRM 555 255pts

#include <bits/stdc++.h>
using namespace std;
#define ll long long
int f[51],n;
int check(ll x)
{
    if(!x)return 0;
    while(x!=1)
    {
        if(x%5)return 0;
        x/=5;
    }
    return 1;
}
class CuttingBitString
{
public:
    int getmin(string s)
    {
        memset(f,0x3f,sizeof(f));
        f[0]=0;n=s.size();
        for(int i=1;i<=n;i++)
        {
            ll t=0;
            for(int j=i-1;j>=0;j--)
            {
                if(s[j]-'0')t=t|(1ll<<(i-j-1));
                if(check(t)&&s[j]-'0')f[i]=min(f[i],f[j]+1);
            }
        }
        return f[n]>n ? -1:f[n];
    }
}cls;

SRM 555 555pts

#include <bits/stdc++.h>
using namespace std;
#define mod 555555555
#define ll long long
int C[3300][3300],ans;
class XorBoard
{
public:
    int count(int h,int w,int c1,int c2,int n)
    {
        for(int i=0;i<=3200;i++)C[i][0]=1;
        for(int i=1;i<=3200;i++)
            for(int j=1;j<=3200;j++)
                C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;

        for(int i=c1&1;i<=h&&i<=c1;i+=2)
            for(int j=c2&1;j<=w&&j<=c2;j+=2)
                if(i*(w-j)+j*(h-i)==n)
                    ans=(ans+(ll)C[h][i]*C[w][j]%mod*
                    C[(c1-i)/2+h-1][h-1]%mod*C[(c2-j)/2+w-1][w-1]%mod)%mod;
        return ans;
    }
}cls;

SRM 555 1055pts

#include <bits/stdc++.h>
using namespace std;
#define ll long long
string s;
int n,m,cnt,top;
ll a[41],c;
int b[41],st[41];
ll ans;
void check(string s)
{
    for(int i=0;i<n;i++)
        if(b[i]!=-1&&b[i]!=s[i]-'0')
            return;
    a[cnt]=0;
    for(int i=0;i<n;i++)
        if(b[i]!=-1)a[cnt]|=1ll<<i;
}
int count(ll x)
{
    int ret=0;
    for(;x;x-=x&-x)ret++;
    return ret;
}
class MapGuessing
{
public:
    ll countPatterns(string s1,vector<string>s2)
    {
        for(int i=0;i<s2.size();i++)s=s+s2[i];
        n=s1.size();m=s.size();
        for(int i=0;i<n;i++)
        {
            a[++cnt]=0;
            memset(b,-1,sizeof(b));
            for(int j=0,now=i;j<m;j++)
            {
                if(s[j]=='<')now--;
                else if(s[j]=='>')now++;
                else b[now]=s[j]-'0';
                if(now<0||now>=n){cnt--;break;}
                check(s1);
            }
        }
        if(cnt)ans=1;
        for(int now=1;now<=cnt;now++)
        {
            top=0;
            for(int i=1;i<now;i++)
                if(a[i]&a[now])st[++top]=i;
            for(int i=0;i<1<<top;i++)
            {
                c=a[now];int sum=0;
                for(int j=0;j<top;j++)
                    if(i>>j&1)
                        c&=a[st[j+1]],sum++;
                if(sum&1)ans-=(1ll<<count(c))-1;
                else ans+=(1ll<<count(c))-1;
            }
        }
        return ans;
    }
}cls;

SRM 563 300pts

#include <bits/stdc++.h>
using namespace std;
int n;
int a[31],b[31],c[31];
string ans;
char c1[1];
int check(int x,string s)
{
    memset(c,0,sizeof(c));
    for(int i=x;i<n;i++)
        c[s[i]]++;
    for(int j=0;j<26;j++)
        if(c[j]<b[j])return 0;
    return 1;
}
class FoxAndHandle
{
public:
    string lexSmallestName(string s)
    {
        n=s.size();
        for(int i=0;i<n;i++)s[i]-='a',a[s[i]]++;
        for(int i=0;i<26;i++)b[i]=a[i]/2;
        for(int i=0,now=0;i<n/2;i++)
        {
            int pos=0,val=27;
            for(int j=now;j<n;j++)
                if(b[s[j]])
                {
                    b[s[j]]--;
                    if(check(j+1,s)&&s[j]<val)
                        val=s[j],pos=j;
                    b[s[j]]++;
                }
            c1[0]=val+'a';
            ans=ans+c1;
            now=pos+1;b[val]--;
        }
        return ans;
    }
};

SRM 563 500pts

#include <bits/stdc++.h>
using namespace std;
int f[61][61][61],n,ans;
void upd(int &x,int y){x=max(x,y);}
class SpellCards
{
public:
    int maxDamage(vector<int>l,vector<int>v)
    {
        n=l.size();
        memset(f,-0x3f,sizeof(f));
        for(int i=0;i<n;i++)
            if(l[i]<=n)f[i][(i+l[i]-1)%n][0]=v[i];
        for(int i=1;i<n;i++)
            for(int j=0;j<n;j++)
                for(int k=0;k<=n;k++)
                {   
                    if(k)upd(f[j][(j+i)%n][k],f[(j+1)%n][(j+i)%n][k-1]);
                    if(k)upd(f[j][(j+i)%n][k],f[j][(j+i-1)%n][k-1]);

                    for(int t=j;t!=(j+i)%n;t=(t+1)%n)
                        for(int w=0;w<=k;w++)
                            upd(f[j][(j+i)%n][k],f[j][t][w]+f[(t+1)%n][(j+i)%n][k-w]);

                    for(int t=l[j]+k-1;t<=n;t++)
                        upd(f[j][(j+i)%n][k],f[(j+1)%n][(j+i)%n][t]+v[j]);

                    upd(ans,f[j][(j+i)%n][k]);
                }
        return ans;
    }
}cls;

SRM 563 950pts

这题是这样的,如果两个点之间有边,那么对于第三个点这两个点一定有一个点和他连边。这样这个算法才是成立的。

#include <bits/stdc++.h>
using namespace std;
#define N 1700
#define ll long long
#define mod 1000000009
#define PA pair<poi,poi> 
int h,w,n,ans;
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
int val[N],deg[N],C[N][N];
bool vis[N][N];
vector<string>s1;
struct poi
{
    int x,y;
    poi(){}
    poi(int x,int y):x(x),y(y){}
    int trs(){return x*w+y;}
    int met(){return s1[x][y]=='#';}
    poi move(int dir){return poi(x+dx[dir],y+dy[dir]);}
    friend bool operator == (const poi &r1,const poi &r2)
    {return r1.x==r2.x&&r1.y==r2.y;}
    friend bool operator != (const poi &r1,const poi &r2)
    {return !(r1==r2);};
};
poi trs(int x){return poi(x/w,x%w);}
int out(poi p1){return p1.x<0||p1.x>=h||p1.y<0||p1.y>=w;}
poi get(poi p,int d,int tp)
{
    int d1=d^2;
    if(tp)
    {
        if(!out(p.move(d1))&&(p.move(d1)).met())return p;
        return poi(-1,-1);
    }
    if(out(p.move(d))||p.move(d).met())return poi(-1,-1);
    return p.move(d);
}
queue<PA>q;
void push(poi p1,poi p2)
{
    if(vis[p1.trs()][p2.trs()]||vis[p2.trs()][p1.trs()])return;
    vis[p1.trs()][p2.trs()]=vis[p2.trs()][p1.trs()]=1;
    q.push(make_pair(p1,p2));
}
int qpow(int x,int y)
{
    int ret=1;
    while(y)
    {
        if(y&1)ret=(ll)ret*x%mod;
        x=(ll)x*x%mod;y>>=1;
    }
    return ret;
}
class CoinsGame
{
public:
    int ways(vector<string>s)
    {
        s1=s;
        h=s.size();w=s[0].size();
        for(int i=0;i<h;i++)
            for(int j=0;j<w;j++)
                for(int k=0;k<h;k++)
                    for(int t=0;t<w;t++)
                    {
                        poi p1(i,j),p2(k,t);
                        if(p1!=p2&&!p1.met()&&!p2.met())
                            for(int r=0;r<4;r++)
                                if(out(p1.move(r))^out(p2.move(r)))
                                    push(p1,p2);
                    }
        while(!q.empty())
        {
            PA t=q.front();q.pop();
            poi p1=t.first,p2=t.second,r1,r2;
            for(int i=0;i<4;i++)
                for(int j=0;j<2;j++)
                {
                    r1=get(p1,i,j);
                    if(!out(r1))for(int k=0;k<2;k++)
                    {
                        r2=get(p2,i,k);
                        if(!out(r2))push(r1,r2);
                    }
                }
        }
        for(int i=0;i<h;i++)
            for(int j=0;j<w;j++)
                if(!poi(i,j).met())
                    val[poi(i,j).trs()]=n++;

        for(int i=0;i<h*w;i++)
            for(int j=0;j<h*w;j++)
                if(vis[i][j])
                    deg[val[i]]++;

        for(int i=0;i<=n;i++)C[i][0]=1;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;

        for(int i=2;i<=n;i++)
        {   
            ll t=0;
            for(int j=0;j<n;j++)
                t=t+(C[n-1][i-1]-C[n-1-deg[j]][i-1]+mod)%mod;
            ans=(ans+t%mod*qpow(i,mod-2)%mod)%mod;
        }
        return ans;
    }
}cls;

SRM 550 300pts

前四步特殊考虑,后面的模拟。

#include <bits/stdc++.h>
using namespace std;
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
int vis[110][110],n,l1,r1,l2,r2;
int check(int x,int y)
{
    if(vis[x+50][y+50])return 0;
    if(x<l1||x>l2||y<r1||y>r2)return 0;
    return 1;
}
class RotatingBot
{
public:
    int minArea(vector<int> a)
    {
        n=a.size();vis[50][50]=1;
        int X=0,Y=0;
        for(int i=0;i<4&&i<n;i++)
        {
            int d=i&3;
            for(int j=1;j<=a[i];j++)
            {
                X+=dx[d];Y+=dy[d];
                if(vis[X+50][Y+50])return -1;
                vis[X+50][Y+50]=1;
                l1=min(l1,X);r1=min(r1,Y);
                l2=max(l2,X);r2=max(r2,Y);
            }
            if(i!=n-1&&check(X+dx[d],Y+dy[d]))return -1;        
        }
        for(int i=4;i<n;i++)
        {
            int d=i&3;
            for(int j=1;j<=a[i];j++)
            {
                X+=dx[d];Y+=dy[d];
                if(!check(X,Y))return -1;
                vis[X+50][Y+50]=1;
            }
            if(i!=n-1&&check(X+dx[d],Y+dy[d]))return -1;
        }
        return (l2-l1+1)*(r2-r1+1);
    }
}cls;

SRM 550 500pts

类似一个分形的东西。画一下图可以知道是一个等腰直角三角形,然后分成四块,其中一块为空,其他三块往下递归。
对于每个点分别求,先扩展到包含这个点的最小的三角形,然后往下递归,看属于哪个方向。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
vector<string>ans;
struct tri
{
    ll x[3],y[3];
    void init()
    {
        x[0]=y[0]=0;
        x[1]=1;y[1]=1;x[2]=2;y[2]=0;
    }
    void rev()
    {
        y[1]=y[1]*2+1;x[1]=x[2]+1;
        x[2]=(x[2]+1)*2;
    }
    int ins(ll x1,ll y1)
    {
        if(y1<y[0])return 0;
        if(y1-x1>y[0]-x[0])return 0;
        if(y1+x1>y[2]+x[2])return 0;
        return 1;
    }
}a,b,c,d;
tri get(tri p,int type)
{
    tri ret=p;
    ll t=(p.y[1]-p.y[0]+1)/2;
    if(type==0)
    {
        ret.y[1]=p.y[1]-t;
        ret.x[1]=p.x[1]-t;
        ret.x[2]=p.x[1]-1;
    }
    else if(type==2)
    {
        ret.y[1]=p.y[1]-t;
        ret.x[1]=p.x[1]+t;
        ret.x[0]=p.x[1]+1;
    }
    else
    {
        ret.y[0]=p.y[0]+t;
        ret.x[0]=p.x[0]+t;
        ret.y[2]=p.y[2]+t;
        ret.x[2]=p.x[2]-t;
    }
    return ret;
}
string get(ll x,ll y,ll n)
{
    if(y>x||x+y>2*(n-1))return string(".");
    a.init();
    while(!a.ins(x,y))
        a.rev();
    while(a.x[1]-a.x[0]!=1)
    {
        b=get(a,0);c=get(a,1);d=get(a,2);
        if(b.ins(x,y))a=b;
        else if(c.ins(x,y))a=c;
        else if(d.ins(x,y))a=d;
        else return string(".");
    }
    if(x==a.x[0]&&y==a.y[0])return string("A");
    if(x==a.x[0]+1&&y==a.y[0])return string(".");
    return string("B");
}
class CheckerExpansion
{
public:
    vector<string> resultAfter(ll n,ll x0,ll y0,int w,int h)
    {
        ans.resize(h);
        for(int i=0;i<h;i++)
            for(int j=0;j<w;j++)
                ans[i]+=get(x0+j,y0+h-i-1,n);
        return ans;
    }
}cls;

SRM 550 950pts

总的操作次数有一个上限,考虑在状态中记录转移一次,两次达到目标的位置个数,那么转移0次的可以用总的减去一次两次的。
总的状态数不超过80。由于终点所在的状态只有一个串与之对应,因此可以用这种状态表示。
可以用矩乘优化转移。由于求的是前缀和,因此需要加一个新点,终点连新点并在新点加一个自环。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 1000000007
int n,cnt;
int val[210],bel[210];
int trs[3][3];
struct matrix
{
    int w[81][81];
    friend matrix operator * (const matrix &r1,const matrix &r2)
    {
        matrix ret;
        memset(&ret,0,sizeof(ret));
        for(int i=1;i<=cnt;i++)
            for(int j=1;j<=cnt;j++)
                for(int k=1;k<=cnt;k++)
                    ret.w[i][j]=(ret.w[i][j]+(ll)r1.w[i][k]*r2.w[k][j]%mod)%mod;
        return ret;
    };
}beg;
matrix qpow(matrix x,int y)
{
    matrix ret;
    for(int i=1;i<=cnt;i++)
        for(int j=1;j<=cnt;j++)
            ret.w[i][j]=(i==j);
    while(y)
    {
        if(y&1)ret=ret*x;
        x=x*x;y>>=1;
    }
    return ret;
}
class ConversionMachine
{
public:
    int countAll(string s1,string s2,vector<int>v,int sum)
    {
        trs[0][1]=v[0];trs[1][2]=v[1];trs[2][0]=v[2];
        trs[0][2]=v[0]+v[1];
        trs[1][0]=v[1]+v[2];
        trs[2][1]=v[2]+v[0];
        n=s1.size();
        for(int i=0;i<=n;i++)
            for(int j=0;j<=n;j++)
                if(i+j<=n)
                    val[++cnt]=i*(n+1)+j,bel[i*(n+1)+j]=cnt;
        for(int i=1;i<=cnt;i++)
        {
            int t1=val[i]/(n+1),t2=val[i]%(n+1),t3=n-t1-t2;
            if(t1)beg.w[i][bel[(t1-1)*(n+1)+t2]]+=t1;
            if(t2)beg.w[i][bel[(t1+1)*(n+1)+(t2-1)]]+=t2;
            if(t3)beg.w[i][bel[t1*(n+1)+(t2+1)]]+=t3;
        }
        beg.w[bel[0]][++cnt]=1;beg.w[cnt][cnt]=1;
        int t1=0,t2=0,c1=1;
        for(int i=0;i<n;i++)
        {
            int t=(s2[i]-s1[i]+3)%3;
            sum-=trs[s1[i]-'a'][s2[i]-'a'];
            if(sum<0)return 0;
            c1+=t;
            if(t==1)t1++;
            if(t==2)t2++;
        }
        c1+=sum/((ll)v[0]+v[1]+v[2])*3;
        beg=qpow(beg,c1);
        return beg.w[bel[t1*(n+1)+t2]][cnt];
    }
}cls;

SRM 549 250pts

#include <bits/stdc++.h>
using namespace std;
#define M 6100
#define inf 1e9
int n,m,cnt,S,T,tot,ans;
int p1[51],p2[51];
int head[110],nex[M],to[M],val[M];
int deep[110];
queue<int>q;
void add(int x,int y,int z)
{
    tot++;
    nex[tot]=head[x];head[x]=tot;
    to[tot]=y;val[tot]=z;
}
void ade(int x,int y,int z)
{add(x,y,z);add(y,x,0);}
int bfs()
{
    memset(deep,-1,sizeof(deep));
    while(!q.empty())q.pop();
    deep[S]=0;q.push(S);
    while(!q.empty())
    {
        int t=q.front();q.pop();
        for(int i=head[t];i;i=nex[i])
            if(val[i]&&deep[to[i]]==-1)
            {
                deep[to[i]]=deep[t]+1;
                q.push(to[i]);
                if(to[i]==T)return 1;
            }
    }
    return 0;
}
int dfs(int x,int mv)
{
    if(x==T)return mv;
    int tmp=0;
    for(int i=head[x];i;i=nex[i])
        if(deep[to[i]]==deep[x]+1&&val[i])
        {
            int t=dfs(to[i],min(val[i],mv-tmp));
            if(!t)deep[to[i]]=-1;
            tmp+=t;
            val[i]-=t;val[i^1]+=t;
            if(tmp==mv)break;
        }
    return tmp;
}
class PointyWizardHats
{
public:
    int getNumHats(vector<int>h1,vector<int>r1,vector<int>h2,vector<int>r2)
    {
        S=++cnt;T=++cnt;tot=1;
        n=h1.size();m=h2.size();
        for(int i=0;i<n;i++)p1[i]=++cnt,ade(S,p1[i],1);
        for(int i=0;i<m;i++)p2[i]=++cnt,ade(p2[i],T,1);

        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                if(r2[j]>r1[i]&&h1[i]*r2[j]>h2[j]*r1[i])
                    ade(p1[i],p2[j],1);
        while(bfs())
            ans+=dfs(S,inf);
        return ans;
    }
}cls;

SRM 549 600pts

#include <bits/stdc++.h>
using namespace std;
#define N 14
#define M 1800000
int h,w,cnt,ans,ret,n1;
char f[N][M],g[M];
int X[N],Y[N],nx[N],ny[N],pw[N];
int count(int x)
{
    int ret=0;
    for(int i=0;i<cnt;i++)
        if(x/pw[i]%3)ret++;
    return ret;
}
int exist(int x)
{
    int ret=0;
    for(int i=0;i<cnt;i++)
        if(x/pw[i]%3==1)ret++;
    return ret;
}
void print(int x)
{
    printf("%d : ",x);
    for(int i=0;i<cnt;i++)
        printf("%d",x/pw[i]%3);
    puts("");
}
int check(int x)
{
    int px[N]={0},py[N]={0};
    for(int i=0;i<cnt;i++)
    {
        if(x/pw[i]%3==0)
            return g[x+pw[i]]||g[x+pw[i]*2];
        else if(x/pw[i]%3==1)
            px[X[i+1]]++,py[Y[i+1]]++;
    }
    if(exist(x)!=n1)return 0;
    for(int i=0;i<h;i++)
        if((px[i]+nx[i])&1)return 0;
    for(int i=0;i<w;i++)
        if((py[i]+ny[i])&1)return 0;
    //print(x);
    return 1;
}
class MagicalHats
{
public:
    int findMaximumReward(vector<string>s,vector<int>v,int n)
    {
        h=s.size();w=s[0].size();n1=v.size();
        for(int i=0;i<h;i++)
            for(int j=0;j<w;j++)
                if(s[i][j]=='H')
                {
                    X[++cnt]=i,Y[cnt]=j;
                    nx[i]++;ny[j]++;
                }
        pw[0]=1;
        for(int i=1;i<=cnt;i++)pw[i]=pw[i-1]*3;
        int flag=0;
        for(int i=pw[cnt]-1;i>=0;i--)
        {
            g[i]=check(i),flag|=g[i];
        //  if(g[i])print(i);
        }
        if(!flag)return -1;
        for(int i=cnt;i>=0;i--)
            for(int j=0;j<pw[cnt];j++)
                if(count(j)==i)
                {
                    if(i==cnt)
                    {
                        f[i][j]=g[j] ? 0:-100;
                        continue;
                    }
                    f[i][j]=-100;
                    for(int k=0;k<cnt;k++)
                        if(j/pw[k]%3==0)
                        {
                            char t1=f[i+1][j+pw[k]],t2=f[i+1][j+pw[k]*2];
                            if(i<n)t1++;
                            if(t1<0)f[i][j]=max(f[i][j],t2);
                            else if(t2<0)f[i][j]=max(f[i][j],t1);
                            else f[i][j]=max(f[i][j],min(t1,t2));
                        }
                }
        sort(v.begin(),v.end());
        for(int i=0;i<f[0][0];i++)ret+=v[i];
        return ret;
    }
}cls;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值