[NOIP simulation 23] solution to a problem

Middle pigeon quite a few ah QAQ ...... have time to fix it ......

A.mine

SBDP , write the examination room but still be able to trouble the giant A's (though the MLE ...... 1 each dimension are less open out on A 555). Provided $ dp [i] [j] [k] $ enumeration to bit i, bit i is j, i-1 of the program is the number of bits k. j and k are integers of 0 to 3, representing the number of front and rear Ray / is mine.

Then vigorously Category talk to

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N=1e6+5;
typedef long long ll;
const ll mod=1e9+7;
char s[N];
int str[N];
ll dp[N][5][5];//到第i位 第i位是j 第i-1位是k
//0 0
//1 1
//2 2
//3 *
int len;
void mmod(ll &x)
{
    while(x>=mod)x=x-mod;
}
bool isbomb(int x)
{
    if(str[x]==4||str[x]==3)return 1;
    return 0;
}
bool judge()
{
    for(int i=1;i<=len;i++)
    {
        if(str[i]==4)continue;
        if(str[i]==1&&(str[i-1]==2||(str[i-1]==3&&str[i+1]==3)||(!isbomb(i-1)&&!isbomb(i+1))))return 0;
        if(str[i]==2&&(!isbomb(i-1)||!isbomb(i+1)))return 0;
    }
    return 1;
}
int main()
{
    scanf("%s",s+1);len=strlen(s+1);
    for(int i=1;i<=len;i++)
        if(s[i]=='2')s[i-1]=s[i+1]='*';
    if(len==1)
    {
        if(s[1]=='*'||s[1]=='0')puts("1");
        else puts("0");
        return 0;
    }
    for(int i=1;i<=len;i++)
    {
        if(s[i]=='0')str[i]=0;
        else if(s[i]=='1')str[i]=1;
        else if(s[i]=='2')str[i]=2;
        else if(s[i]=='*')str[i]=3;
        else if(s[i]=='?')str[i]=4;
    }
    if(!judge())
    {
        puts("0");
        return 0;
    }
    if(str[1]!=4)
    {
        if(str[1]==1)dp[1][1][0]=1;
        else if(str[1]==3)dp[1][3][1]=1;
        else if(str[1]==0)dp[1][0][0]=1;
    }
    else dp[1][1][0]=dp[1][3][1]=dp[1][0][0]=1;
    for(int i=2;i<=len;i++)
    {
    //    cout<<str[i]<<endl;
        if(str[i]==0||str[i]==4)
        {
            mmod(dp[i][0][1]+=dp[i-1][1][3]);
            mmod(dp[i][0][0]+=(dp[i-1][0][1]+dp[i-1][0][0]));
        }
        if(str[i]==1||str[i]==4)
        {
            mmod(dp[i][1][3]+=dp[i-1][3][1]+dp[i-1][3][2]+dp[i-1][3][3]);
            mmod(dp[i][1][0]+=dp[i-1][0][1]+dp[i-1][0][0]);
            mmod(dp[i][1][1]+=dp[i-1][1][3]);
        }
        if(str[i]==2||str[i]==4)
        {
            mmod(dp[i][2][3]+=dp[i-1][3][2]+dp[i-1][3][1]+dp[i-1][3][3]);
        }
        if(str[i]==3||str[i]==4)
        {
            mmod(dp[i][3][1]+=dp[i-1][1][0]+dp[i-1][1][1]);
            mmod(dp[i][3][2]+=dp[i-1][2][3]);
            mmod(dp[i][3][3]+=dp[i-1][3][1]+dp[i-1][3][2]+dp[i-1][3][3]);
        }
    }
    ll ans=0;
    if(str[len]!=4&&str[len-1]!=4)ans=dp[len][str[len]][str[len-1]];
    else if(str[len]==4&&str[len-1]!=4)
    {
        for(int i=0;i<=3;i++)
        {
            int j=str[len-1];
            if(i==0&&(j==3||j==2))continue;
            if(i==1&&(j!=3))continue;
            if(i==2)continue;
            if(i==3&&j==0)continue;
            mmod(ans+=dp[len][i][str[len-1]]);
        }
    }
    else if(str[len]!=4&&str[len-1]==4)
    {
        for(int j=0;j<=3;j++)
        {
            int i=str[len];
            if(i==0&&(j==3||j==2))continue;
            if(i==1&&(j!=3))continue;
            if(i==2)continue;
            if(i==3&&j==0)continue;
            mmod(ans+=dp[len][str[len]][j]);
        }
    }
    else
    {
        for(int i=0;i<=3;i++)
            for(int j=0;j<=3;j++)
            {
                if(i==0&&(j==3||j==2))continue;
                if(i==1&&(j!=3))continue;
                if(i==2)continue;
                if(i==3&&j==0)continue;
                mmod(ans+=dp[len][i][j]);
            }                
    }
    cout<<ans<<endl;
    return 0;
}
View Code

 

A beginning that $ judge () $ is judged illegal situation. A suddenly found out after I start the program seems to encounter a situation or there will not be a legitimate program, so special sentenced a bit.

B.water

The final height of a block (initial height + height of water) is a minimum value out of the maximum value on the rectangular path from this block, i.e., the path is defined as the weight value takes the shortest path weights and max instead of after. Then directly adjacent construction block diagram block boundaries are connected to a source, then dj can run from the source. A bit like a network flow.

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#include<map>
#define pa pair<int,int>
using namespace std;
int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int N=305,M=500005;
const int dx[5]={0,1,0,-1},
          dy[5]={1,0,-1,0};
int n,m;
int a[N][N];
int to[M],nxt[M],head[M],len[M],tot;
void add(int x,int y,int z)
{
    to[++tot]=y;
    nxt[tot]=head[x];
    len[tot]=z;
    head[x]=tot;
}
int id(int i,int j){return (i-1)*m+j;}
int dis[M],vis[M];
void dj(int s)
{
    memset(dis,0x3f,sizeof(dis));
    priority_queue<pa> q;
    dis[s]=0;q.push(make_pair(0,s));
    while(!q.empty())
    {
        int x=q.top().second;q.pop();
        if(vis[x])continue;
        vis[x]=1;
        for(int i=head[x];i;i=nxt[i])
        {
            int y=to[i];
            if(dis[y]>max(dis[x],len[i]))
            {
                dis[y]=max(dis[x],len[i]);
                q.push(make_pair(-dis[y],y));
            }
        }
    }
}

int main()
{
    n=read();m=read();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            a[i][j]=read();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            for(int k=0;k<4;k++)
            {
                int nx=i+dx[k],ny=j+dy[k];
                if(nx<1||nx>n||ny<1||ny>m)add(n*m+1,id(i,j),max(a[i][j],0)),add(id(i,j),n*m+1,max(a[i][j],0));
                else add(id(i,j),id(nx,ny),max(a[i][j],a[nx][ny]));
            }
        }
    dj(n*m+1);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
            printf("%d ",dis[id(i,j)]-a[i][j]);
        putchar('\n');
    }
    return 0;
}
View Code

C.gcd

Number Theory dressed cancer data structure problem.

The need to maintain three quantities:

$ F [] $: i is the selected number set for the number of gcd

$ G [] $: gcd selected set of multiples of the number of i

The number of the selected set of multiples of i: $ s [] $

First $ S [] is a good value of $ obtained enumerate $ I $ factor when the number of each addition, $ s [i] ++ $ to.

Meaning that $ s [] $ What is it? It can help us to quickly get $ g [] $. Obviously $ g [i] = C_ {s [i]} ^ 2 $.

And because $ g [i] = \ sum \ limits_ {i | d} f [d] $, may be a second type of Mobius inversion:

$f[i]=\sum \limits_{i|d} \mu (\frac{d}{i}) g[d]$

$ F [1] $ is also desired, so that the number of factors enumerated changes each time the selected state changes, updates its S $ [] $, and thus updates its $ g [] $.

ans by subtracting the original plus the new g g get.

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N=200005,M=500005;
int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return x*f;
}
typedef long long ll;
bool vis[M];
int pr[M],tot,mu[M];
void ini()
{
    mu[1]=1;
    for(int i=2;i<=M-5;i++)
    {
        if(!vis[i])pr[++tot]=i,mu[i]=-1;
        for(int j=1;j<=tot&&i*pr[j]<=M-5;j++)
        {
            vis[i*pr[j]]=1;
            if(i%pr[j])mu[i*pr[j]]=-mu[i];
            else
            {
                mu[i*pr[j]]=0;
                break;
            }
        }
    }
}
int n,m;
int s[M],ctrl[N],a[N];
int main()
{
    n=read();m=read();
    ini();
    for(int i=1;i<=n;i++)
        a[i]=read();
    ll ans=0;
    while(m--)
    {
        int x=read();
        for(int i=1;i*i<=a[x];i++)
        {
            if(a[x]%i==0)
            {
                if(!ctrl[x])ans+=1LL*mu[i]*s[i];
                else ans-=1LL*(s[i]-1)*mu[i];
                if(ctrl[x])s[i]--;
                else s[i]++;
                if(i*i==a[x])continue;
                if(!ctrl[x])ans+=1LL*mu[a[x]/i]*s[a[x]/i];
                else ans-=1LL*(s[a[x]/i]-1)*mu[a[x]/i];
                if(ctrl[x])s[a[x]/i]--;
                else s[a[x]/i]++;
            }
        }
        ctrl[x]^=1;
        printf("%lld\n",ans);
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/Rorschach-XR/p/11366491.html
Recommended