NOIP 2017

小凯的疑惑

题目
放一个比较简洁的证明。
不妨设\(b>a\)
设答案为\(c\)
因为\((a,b)=1\),所以有\(c\equiv ax(\mod b)(x\in[1,b))\)\(c=ax+by(x\in[1,b))\)
\(y\le0\),那么\(c\)显然是可以由\(a,b\)表示的。
因此若要\(c\)不能被表示,需要满足\(y<0\)
因此当\(x=b-1,y=-1\)时,最大的\(c=ab-a-b\)

#include<cstdio>
int main()
{
    int a,b;
    scanf("%d%d",&a,&b);
    printf("%lld",1ll*a*b-a-b);
}

时间复杂度

题目
开个栈模拟就好了。

#include<bits/stdc++.h>
using namespace std;
const int N=107;
int l,O,used[26],vis[26];
string str,code[N];
stack<int>stk;
int read(int &p,string s)
{
    int ans=0;
    while(s[p]<'0'||s[p]>'9'&&p<s.size()) { if(s[p]=='n') return ++p,10000000; ++p; }
    while(s[p]>='0'&&s[p]<='9') ans=ans*10+s[p]-'0',++p;
    return ans;
}
int getO(){int p=3;if(str[2]=='n') return read(p,str); else return 0;}
int calc()
{
    while(!stk.empty()) stk.pop();
    int ans=0,now=0,a,b,p,x,k=-1;
    memset(used,0,sizeof used),memset(vis,0,sizeof vis);
    for(int i=1;i<=l;++i)
    {
    if(code[i][0]=='F')
    {
        
        if(used[x=code[i][2]-'a']) return -1;
        stk.push(x),used[x]=1,p=4,a=read(p,code[i]),b=read(p,code[i]);
        if(b-a>1000) if(k==-1) ++now,ans=max(ans,now),vis[x]=1;
        if(a>b) if(k==-1) k=x;
    }
    if(code[i][0]=='E')
    {
        if(stk.empty()) return -1;
        x=stk.top(),stk.pop(),used[x]=0;
        if(k==x) k=-1;
        if(vis[x]) vis[x]=0,--now;
    }
    }
    if(stk.size()) return -1;
    return ans;
}
int main()
{
    int T,ans,i;
    scanf("%d",&T);
    while(T--)
    {
    for(scanf("%d ",&l),getline(cin,str),O=getO(),i=1;i<=l;++i) getline(cin,code[i]);
    if((ans=calc())==-1) puts("ERR"); else if(ans==O) puts("Yes"); else puts("No");
    }
}

逛公园

题目
首先处理出可能在答案路径上的边。
然后拓扑排序看下有没有环。
如果有环那么一定是一个\(0\)环,有无数解。
否则dp一下求方案数就好了。

#include<bits/stdc++.h>
#define pi pair<int,int>
#define pb push_back
using namespace std;
int read(){int x=0,c=getchar();while(!isdigit(c))c=getchar();while(isdigit(c))x=x*10+c-48,c=getchar();return x;}
const int N=100007;
vector<pi>E[N];priority_queue<pi>q;stack<int>Q;
struct edge{int u,v,w;}e[N<<1];
int n,m,k,P,cnt,Tvis,dis[2][N],vis[N],deg[N],pos[N],f[N][51];
void inc(int &a,int b){a+=b,a=a>=P? a-P:a;}
void clearedge(){for(int i=1;i<=n;++i)E[i].clear();}
void cleardeg(){memset(deg,0,n+1<<2);}
void add(int u,int v,int w){E[u].pb(pi(v,w));}
void dij(int S,int id)
{
    memset(dis[id],0x3f,n+1<<2),++Tvis,q.push(pi(dis[id][S]=0,S));int u;
    while(!q.empty())
    {
    u=q.top().second,q.pop();if(vis[u]==Tvis)continue;vis[u]=Tvis;
    for(auto [v,w]:E[u])if(dis[id][u]+w<dis[id][v])dis[id][v]=dis[id][u]+w,q.push(pi(-dis[id][v],v));
    }
}
void toposort()
{
    cnt=0;int u;Q.push(1);
    while(!Q.empty())
    {
    u=Q.top(),Q.pop(),pos[++cnt]=u;
    for(auto [v,w]:E[u])if(!(--deg[v]))Q.push(v);
    }
}
int main()
{
    int i,j,flg;
    for(int T=read();T;--T)
    {
    n=read(),m=read(),k=read(),P=read();
    for(i=1;i<=m;++i)e[i]=(edge){read(),read(),read()};
    clearedge();
    for(i=1;i<=m;++i)add(e[i].u,e[i].v,e[i].w);
    dij(1,0);
    clearedge();
    for(i=1;i<=m;++i)add(e[i].v,e[i].u,e[i].w);
    dij(n,1);
    clearedge(),cleardeg();
    for(i=1;i<=m;++i)if(dis[0][e[i].u]+dis[1][e[i].v]+e[i].w<=dis[0][n]+k&&dis[0][e[i].u]+e[i].w==dis[0][e[i].v])add(e[i].u,e[i].v,0),++deg[e[i].v];
    for(i=1;i<=m;++i)e[i].w=dis[0][e[i].u]+e[i].w-dis[0][e[i].v];
    toposort();
    flg=0;
    for(i=1;i<=n;++i)if(deg[i]){flg=1;break;}
    if(flg){puts("-1");continue;}
    memset(f,0,sizeof f),f[1][0]=1;
    for(i=0;i<=k;++i)
    {
        for(j=1;j<=cnt;++j)for(auto [v,w]:E[pos[j]])inc(f[v][i],f[pos[j]][i]);
        for(j=1;j<=m;++j)if(e[j].w&&i+e[j].w<=k)inc(f[e[j].v][i+e[j].w],f[e[j].u][i]);
    }
    for(i=flg=0;i<=k;++i)inc(flg,f[n][i]);
    printf("%d\n",flg);
    }
}

猜你喜欢

转载自www.cnblogs.com/cjoierShiina-Mashiro/p/11853192.html