11.3NOIP模拟赛

/*
考虑贪心 
把原序列排序后,对于原中位数往后所有比要更改到的值小的都改成它
正确性显然。 
*/ 
#include<iostream>
#include<cstdio>
#include<algorithm>

#define N 100007
#define ll long long

using namespace std;
ll n,m,ans,cnt;
ll a[N],sum[N];

inline ll read()
{
    ll x=0,f=1;char c=getchar();
    while(c>'9'||c<'0'){if(c=='0')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}

int main()
{
    freopen("median.in","r",stdin);
    freopen("median.out","w",stdout);
    n=read();m=read();
    if(m==0) {printf("0\n");return 0;}
    for(int i=1;i<=n;i++) a[i]=read();
    int mid=n/2+1; sort(a+1,a+n+1);
    for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];
    int num=lower_bound(a+1,a+n+1,m)-a;
    if(num==n+1) ans=mid*m-(sum[n]-sum[mid-1]);
    else if(num==mid) ans=max(a[mid],m)-min(a[mid],m);
    else ans=(num-mid)*m-(sum[num-1]-sum[mid-1]);
    cout<<ans<<endl;
    fclose(stdin);fclose(stdout);
    return 0;
} 

 

/*
水水的dp 
然而菜死了没想出正解QAQ 
*/ 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>

#define N 3001
#define ll long long
#define mod 233333333

using namespace std;
ll n,m,k,p,ans,cnt,cur,res1,res2;
ll f[N][N];

inline ll read()
{
    ll x=0,f=1;char c=getchar();
    while(c>'9'||c<'0'){if(c=='0')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}

void dfs(int now,int tot)
{
    if(now && now-tot*2>=k) return;
    if(tot>n) return;
    if(now==n*2 && tot==n)
    {
        ans++;ans%=p;
        return;
    }
    dfs(now+1,tot);dfs(now+1,tot+1);
}

ll min_(ll a,ll b){return a<b?a:b;}

int main()
{
    freopen("term.in","r",stdin);
    freopen("term.out","w",stdout);
    n=read();k=read();p=read();
    if(n<=10)
    {
        dfs(0,0);
        cout<<ans%p<<endl;
    }
    else
    {
        f[0][0]=1;
        for(int i=1;i<=n*2;i++) for(int j=0;j<=min_(n,i);j++)
              if(i-2*j<k) f[i][j]+=(f[i-1][j]+f[i-1][j-1])%p;
        cout<<f[2*n][n]%p;
    }
    fclose(stdin);fclose(stdout);
    return 0;
}
60暴力

 

/*
K=1显然是Catalan数
考虑Catalan数的证明过程
若数列不合法,则一定存在一个位置x,在这之前有m个+1,m + k个-1
我们把之后的1变为-1,-1变为1
则该序列含有N + K个-1, N个1
方案数为C(2n, n + k)
用总的减去即可
*/
#include<cstdio>
#include<cstring>
#define LL int

const int MAXN = 2 * 1e6 + 10;

inline int read()
{
    int x=0,f=1;char c=getchar();
    while(c>'9'||c<'0'){if(c=='0')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int N, mod, prime[MAXN], vis[MAXN], tot, mn[MAXN], num[MAXN], K;
void GetPhi(int N)
{
    vis[1] = 1;
    for(int i = 2; i <= N; i++)
    {
        if(!vis[i]) prime[++tot] = i, mn[i] = tot;
        for(int j = 1; j <= tot && (i * prime[j] <= N); j++)
        {
            vis[i * prime[j]] = 1;
            mn[i * prime[j]] = j;
            if(!(i % prime[j])) break;
        }
    }
}
void insert(int x, int opt)
{
    while(x != 1) num[mn[x]] += opt, x = x / prime[mn[x]];
}
int fastpow(int a, int p)
{
    int base = 1;
    while(p)
    {
        if(p & 1) base = (1ll * base * a) % mod;
        a = (1ll * a * a) % mod;
        p >>= 1;
    }
    return base;
}
int FindAns()
{
    LL ans = 1;
    for(int i = 1; i <= tot; i++)
        if(num[i])
            ans = (1ll * ans * fastpow(prime[i], num[i])) % mod;
    return ans;
}
main()
{
    N = read();K = read();mod = read();
    GetPhi(2 * N);
    for(int i = N + 1; i <= 2 * N; i++) insert(i, 1);
    for(int i = 1; i <= N; i++) insert(i, -1);
    LL ans1 = FindAns();
    memset(num, 0, sizeof(num));

    for(int i = N + K + 1; i <= 2 * N; i++) insert(i, 1);
    for(int i = 1; i <= N - K; i++) insert(i, -1);
    LL ans2 = FindAns();
    printf("%lld", (ans1 - ans2 + mod) % mod);
    return 0;
}

 

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>

#define N 200007
#define M 500007
#define inf 0x3f3f3f3f

using namespace std;
int n,m,ans,cnt,top,num,S,T;
int vis[N],val[N],head[N],val_[N],siz[N];
int dfn[N],low[N],sta[N],scc[N],to[N];
bool in_st[N];
int dis[20][20],d[N];
int Head[N];
struct edge{
    int u,v,nxt,w;
}e[M],E[M];
struct node{
    int sum,x;
};

inline int read()
{
    int x=0,f=1;char c=getchar();
    while(c>'9'||c<'0'){if(c=='0')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}

inline void add(int u,int v,int w)
{
    e[++cnt].v=v;e[cnt].nxt=head[u];e[cnt].w=w;head[u]=cnt;
}

inline void Add(int u,int v,int w)
{
    E[++cnt].v=v;E[cnt].nxt=Head[u];E[cnt].w=w;Head[u]=cnt;
}

void Tarjan(int u)
{
    low[u]=dfn[u]=++cnt;sta[++top]=u;in_st[u]=1;
    for(int i=head[u];i;i=e[i].nxt)
    {
        int v=e[i].v;
        if(!dfn[v]) 
          Tarjan(v),low[u]=min(low[u],low[v]);
        else if(in_st[v]) low[u]=min(low[u],dfn[v]);
    }
    int lol=0;
    if(low[u]==dfn[u])
    {
        num++;
        while(u!=sta[top])
        {
            lol++;
            if(sta[top]==S) to[num]=1;
            if(sta[top]==T) to[num]=2;
            in_st[sta[top]]=0;scc[sta[top]]=num;top--;
        }
        in_st[sta[top]]=0;scc[sta[top]]=num;top--;
        siz[num]=++lol;
    }
}

void bfs()
{
    queue<node>q;node u;
    while(!q.empty()) q.pop();
    u.x=scc[S];u.sum=val_[scc[S]];vis[scc[S]]=1;
    q.push(u);
    while(!q.empty())
    {
        u=q.front();q.pop();
        if(u.x==scc[T]) ans=min(ans,u.sum);
        for(int i=Head[u.x];i;i=E[i].nxt)
        {
            int v=E[i].v;node tmp;
            tmp.sum=u.sum & E[i].w & val_[v];tmp.x=v;
            q.push(tmp);
        }
    }
}

int main()
{
    freopen("rabbit.in","r",stdin);
    freopen("rabbit.out","w",stdout);
    int x,y,z;memset(dis,127/3,sizeof dis);
    n=read();m=read();S=read();T=read();
    for(int i=1;i<=n;i++) val[i]=read();
    for(int i=1;i<=m;i++) 
    {
        x=read();y=read();z=read();
        add(x,y,z);
    }cnt=0;ans=inf;    
    for(int i=1;i<=n;i++) if(!dfn[i]) Tarjan(i);
    for(int i=1;i<=num;i++) for(int j=1;j<=n;j++)
    {
        if(scc[j]==i)
        {
            if(siz[j]==1) val_[i]=val[j];
            else
            {
                for(int x=head[j];x;x=e[x].nxt)
                    if(scc[e[x].v]==num) val_[scc[j]]&=val[j]&val[e[x].v]&e[j].w;
            }
        }
    }
    cnt=0;
    for(int i=1;i<=n;i++) 
    {
        for(int j=head[i];j;j=e[j].nxt)
        {
            if(scc[i]!=scc[e[j].v]) Add(scc[i],scc[e[j].v],e[j].w);
        }
    }
    bfs();
    printf("%d\n",ans);
    return 0;
    return 0;
}
10分蜜汁WA的暴力

std可能有锅?

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<iostream>
#include<ctime>
#include<cmath>
#include<set>
#include<map>
#define ll long long
#define M 700010
struct Edge {
    int vi, vj, v;
} edge[M];
struct Note {
    int vj, v, id;
} be;
using namespace std;
int read() {
    int nm = 0, f = 1;
    char c = getchar();
    for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
    return nm * f;
}
vector<int>to[M];
vector<Note> to1[M], to2[M];
int belong[M], st[M], dfn[M], low[M], dft, n, m, s, t, note[M], noww[M], tp, tot, sz[M], ans = 2147483647, rudu1[M], rudu2[M];
bool vis[M];
void tarjan(int now) {
    vis[now] = true;
    st[++tp] = now;
    dfn[now] = low[now] = ++dft;
    for(int i = 0; i < to[now].size(); i++) {
        int vj = to[now][i];
        if(!dfn[vj]) {
            tarjan(vj);
            low[now] = min(low[now], low[vj]);
        } else if(vis[vj]) low[now] = min(low[now], dfn[vj]);
    }
    if(dfn[now] == low[now]) {
        tot++;
        while(st[tp] != now) {
            int x = st[tp];
            vis[x] = false;
            noww[tot] &= note[x];
            belong[x] = tot;
            tp--;
        }
        int x = st[tp];
        vis[x] = false;
        noww[tot] &= note[x];
        belong[x] = tot;
        tp--;
    }
}
bool can[M], tmp1[M], tmp2[M];
int note1[M], note2[M], tp1, tp2;

void tuopu() {
    queue<int>q;
    q.push(belong[t]);
    while(!q.empty()) {
        int op = q.front();
        q.pop();
        for(int i = 0; i < to2[op].size(); i++) {
            int vj = to2[op][i].vj;
            rudu2[vj]++;
            if(!vis[vj]) q.push(vj), vis[vj] = true;
        }
    }
    while(!q.empty()) q.pop();
    q.push(belong[s]);
    while(!q.empty()) {
        int op = q.front();
        note1[++tp1] = op;
        q.pop();
        for(int i = 0; i < to1[op].size(); i++) {
            int vj = to1[op][i].vj;
            rudu1[vj]--;
            if(rudu1[vj] == 0) q.push(vj);
        }
    }
    q.push(belong[t]);
    while(!q.empty()) {
        int op = q.front();
        q.pop();
        note2[++tp2] = op;
        for(int i = 0; i < to2[op].size(); i++) {
            int vj = to2[op][i].vj;
            rudu2[vj]--;
            if(rudu2[vj] == 0) q.push(vj);
        }
    }
}

void work(int x) {
    for(int i = 1; i <= tot; i++) tmp1[i] = tmp2[i] = false;
    if((noww[belong[s]] & x) == 0) tmp1[belong[s]] = true;
    for(int i = 1; i <= tp1; i++) {
        int op = note1[i];
        for(int j = 0; j < to1[op].size(); j++) {
            be = to1[op][j];
            if((tmp1[op] == true) || (can[be.id] && ((be.v & x) == 0))) {
                tmp1[be.vj] = true;
                tmp1[be.id] = true;
            } else if((noww[be.vj] & x) == 0 && (can[be.vj])) tmp1[be.vj] = true;
        }
    }
    if((noww[belong[t]] &x) == 0) tmp2[belong[t]] = true;
    for(int i = 1; i <= tp2; i++) {
        int op = note2[i];
        for(int j = 0; j < to2[op].size(); j++) {
            be = to2[op][j];
            if((tmp2[op] == true) || (can[be.id] && ((be.v & x) == 0))) {
                tmp2[be.vj] = true;
                tmp2[be.id] = true;
            } else if((noww[be.vj] & x) == 0 && (can[be.vj])) tmp2[be.vj] = true;
        }
    }
    for(int i = 1; i <= tot; i++) tmp1[i] = (tmp1[i] | tmp2[i]);
    if(tmp1[belong[s]] && tmp1[belong[t]]) ans -= x;
    else return;
    for(int i = 1; i <= tot; i++) can[i] = (can[i] & tmp1[i]);
}
int main() {
    freopen("rabbit.in", "r", stdin);
    freopen("rabbit.out", "w", stdout);
    cin >> n >> m >> s >> t;
    for(int i = 1; i <= n; i++) note[i] = read(), noww[i] = 2147483647;
    for(int i = 1; i <= m; i++) {
        int vi = read(), vj = read(), v = read();
        edge[i].vi = vi, edge[i].vj = vj, edge[i].v = v;
        to[vi].push_back(vj);
    }
    tarjan(s);
    if(!dfn[t]) {
        puts("-1");
        return 0;
    }
    for(int i = 1; i <= m; i++) {
        int vi = edge[i].vi, vj = edge[i].vj, v = edge[i].v;
        vi = belong[vi], vj = belong[vj];
        if(vi == 0 || vj == 0) continue;
        if(vi == vj) noww[vi] &= v;
        else {
            be.id = ++tot;
            be.vj = vj;
            be.v = v;
            to1[vi].push_back(be);
            rudu1[vj]++;
            be.vj = vi;
            to2[vj].push_back(be);
        }
    }
    if(belong[s] == belong[t]) {
        cout << noww[belong[s]] << "\n";
        return 0;
    }
    tuopu();
    for(int i = 1; i <= tot; i++) can[i] = true;
    for(int i = 30; i >= 0; i--) work(1 << i);
    cout << ans << "\n";
    return 0;
}
std

 

posted @ 2018-11-03 16:11  安月冷  阅读(181)  评论(0编辑  收藏  举报