2019 杭电多校第三场 题解

题解


1001 Azshara's deep sea

Unsolved.

1002 Blow up the city.

 题解:倒着建图,然后将原图出度为零的点用一个新节点连接起来,支配树板题。

参考代码:

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
//DAG图q个询问,给你u,v:去掉一个点连同和这个点相连的所有边使得u或v不能到达出度为零的点的方案 
const int maxn=2e5+7;
int n,m,deg[maxn],rt,a[maxn],dep[maxn],val[maxn];
int f[maxn][20];
vector<int>E[maxn],RE[maxn];
void Topsort()
{
    queue<int>q;
    rt=n+1;//图可能不连通,建一个新点连接起来 
    for(int i=1;i<=n;i++) if(!deg[i]){q.push(i);E[rt].pb(i);RE[i].pb(rt);}
    int tot=0;
    while(!q.empty())
    {
        int u=q.front(); q.pop();
        a[++tot]=u;
        for(auto &v:E[u]){if((--deg[v])==0) q.push(v);}
    }
}
int LCA(int x,int y)
{
    if(dep[x]>dep[y]) swap(x,y);
    for(int i=19;i>=0;i--)
    {
        if(dep[y]>dep[x]&&dep[f[y][i]]>=dep[x]) 
            y=f[y][i];
    }
    if(x==y) return x;
    for(int i=19;i>=0;i--)
    { 
        if(f[x][i]!=f[y][i]) 
            x=f[x][i],y=f[y][i];
    }
    return f[x][0];
}
void Work()
{
    dep[rt]=1;
    for(int i=1;i<=n;i++)
    {
        int u=a[i],fa=-1;
        for(auto &v:RE[u]) fa=(fa==-1? v:LCA(fa,v));
        dep[u]=dep[fa]+1;
        f[u][0]=fa; 
        for(int i=1;i<=19;i++) f[u][i]=f[f[u][i-1]][i-1];
    }
}
int main()
{
    int tt; 
    scanf("%d",&tt);
    while(tt--)
    {
        scanf("%d%d",&n,&m);
        memset(f,0,sizeof(f)); 
        for(int i=1;i<=n+1;i++) 
        {
            E[i].clear(); RE[i].clear();
            dep[i]=deg[i]=0;
        }
        while(m--) 
        {
            int u, v; 
            scanf("%d%d", &u, &v);
            E[v].pb(u); RE[u].pb(v); deg[u]++;
        }
        
        Topsort(); Work();
        int q; 
        scanf("%d", &q);
        while(q--)
        {
            int u, v; 
            scanf("%d%d",&u,&v);
            int lca=LCA(u,v);
            printf("%d\n",dep[u]+dep[v]-dep[lca]-1);
        }
    }
    
    return 0;
}
View Code

1003 Yukikaze and Demons

Unsolved.

1004 Distribution of books

https://blog.csdn.net/liufengwei1/article/details/97703075

#include<bits/stdc++.h>
using namespace std;
#define maxl 200010


int n,tot,cnt,k;
long long up,dow,ans;
int a[maxl],b[maxl],dp[maxl],h[maxl],c[maxl];
long long sum[maxl];
long long num[maxl];


inline void prework()
{
    scanf("%d%d",&n,&k);
    up=0;dow=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        sum[i]=sum[i-1]+a[i],num[i]=sum[i];
        if(a[i]>0) up+=a[i];
        else dow+=a[i];
    }
    num[n+1]=0;
    sort(num+1,num+2+n);
    tot=unique(num+1,num+2+n)-num-1;
    for(int i=0;i<=n;i++)
        b[i]=lower_bound(num+1,num+1+tot,sum[i])-num;
}

inline void upd(int i,int x) 
{
    int t;
    while(i<=tot && i)
    {
        h[i]=c[i];
        for(int k=1;k<(i&-i);k<<=1)
            h[i]=max(h[i],h[i-k]);
        i+=i&-i;
    }
}
inline int qry(int l,int r)
{
    int ret=-n-1,len=r-l+1;
    while(len && r)
    {
        if(len<(r&-r))
        {
            ret=max(ret,c[r]);
            r--;len--;
        }else
        {
            ret=max(ret,h[r]);
            len-=(r&-r);
            r-=r&-r;                
        }
    }
    return ret;
}

inline bool jug(long long mid)
{
    for(int i=1;i<=n;i++)
        dp[i]=0;
    for(int i=1;i<=tot;i++)
        h[i]=-n-1,c[i]=-n-1;
    int l=1,r=n,id,tmp;
    c[b[0]]=0;upd(b[0],c[b[0]]);
    for(int i=1;i<=n;i++)
    {
        id=lower_bound(num+1,num+1+tot,sum[i]-mid)-num;
        if(id>tot)
            continue;
        tmp=qry(id,tot);
        if(tmp<=-n-1)
            continue;
        dp[i]=max(dp[i],qry(id,tot)+1);
        c[b[i]]=max(c[b[i]],dp[i]);
        upd(b[i],c[b[i]]);
        if(dp[i]>=k)
            return true;
    }
        return false;
}

inline void mainwork()
{
    long long l=dow,r=up,mid;
    while(l+1<r)
    {
        mid=(l+r)>>1;
        if(jug(mid))
            r=mid;
        else
            l=mid;
    }
    if(jug(l))
        ans=l;
    else
        ans=l+1;
}

inline void print()
{
    printf("%lld\n",ans);
}

int main()
{
    int t;
    scanf("%d",&t);
    for(int i=1;i<=t;i++)
    {
        prework();
        mainwork();
        print();
    }
    return 0;
}
View Code

1005 Easy Math Problem

Unsolved.

1006 Fansblog

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
unordered_map<LL,LL> mp;
LL quick_pow(LL a,LL b,LL mod)
{
    LL ans=1;
    while(b)
    {
        if(b&1) ans=((__int128)ans)*a%mod;
        a=((__int128)a)*a%mod;
        b>>=1;
    }
    return ans;
}
long long factor[110], cnt;
long long Mul_Mod(long long a, long long b, long long c) {
    if (b == 0)
        return 0;
    long long ans = Mul_Mod(a, b / 2, c);
    ans = (ans * 2) % c;
    if (b % 2)
        ans = (ans + a) % c;
    return ans;
}
long long Pow_Mod(long long a, long long b, long long c) {
    if (b == 0)
        return 1;
    long long x = Pow_Mod(a, b / 2, c);
    if (x == 0)
        return 0;
    long long y = Mul_Mod(x, x, c);
    if (y == 1 && x != 1 && x != c - 1)
        return 0;
    if (b % 2)
        y = Mul_Mod(y, a, c);
    return y;
}
bool Miller_rabin(long long n, int timenum = 10) {
    if (n < 2)
        return false;
    if (n == 2)
        return true;
    while (timenum--) {
        if (Pow_Mod(rand() % (n - 2) + 2, n - 1, n) != 1)
            return false;
    }
    return true;
}
long long Gcd(long long a, long long b) {
    long long t;
    while (b) {
        t = a;
        a = b;
        b = t % b;
    }
    return a;
}
void Pollard(long long n);
 
void Factor(long long n) {
    long long d = 2;
    while (true) {
        if (n % d == 0) {
            Pollard(d);
            Pollard(n / d);
            return;
        }
        d++;
    }
}
void Pollard(long long n) {
    if (n == 1)
        return;
    if (Miller_rabin(n)) {
        factor[cnt++] = n;
        return;
    }
    long long i = 0, k = 2, x, y, d;
    x = y = rand() % (n - 1) + 1;
    while (i++ < 123456) {
        x = (Mul_Mod(x, x, n) + n - 1) % n;
        d = Gcd((y - x + n) % n, n);
        if (d != 1) {
            Pollard(d);
            Pollard(n / d);
            return;
        }
        if (i == k) {
            y = x;
            k *= 2;
        }
    }
    Factor(n);
}
int main()
{
    int t;
    scanf("%d",&t);
    LL p;
    while(t--)
    {
        scanf("%lld",&p);
        if(mp.count(p))
        {
            printf("%lld\n",mp[p]);
            continue;
        }
        LL ans=p-1;
        if(Miller_rabin(p-2))
        {
            LL ret=(LL)(((__int128)(p-1))*quick_pow(p-1,p-2,p)%p);
            mp[p]=ret;
            printf("%lld\n",ret);
            continue;
        }
        for(LL i=p-4;i>=998244353;i-=2)
        {
            ans=(__int128)ans*(i+1)%p*(i+2)%p;
            if(Miller_rabin(i))
            {
                LL ret=(LL)(((__int128)(p-1))*quick_pow(ans,p-2,p)%p);
                mp[p]=ret;
                printf("%lld\n",ret);
                break;
            }
        }
    }
}
View Code

1007 Find the answer

#include<bits/stdc++.h>
#define maxl 200010
using namespace std;

int n,m;
int a[maxl],dy[maxl],ans[maxl];
struct anode
{
    int id,val;
}aa[maxl];
struct node
{
    int l,r;
    long long sum;
}tree[maxl*4];
int b[maxl];

inline bool cmp(const anode &x,const anode &y)
{
    return x.val<y.val;
}

inline void add(int i,int x)
{
    while(i<=n)
    {
        b[i]+=x;
        i+=i&-i;
    }
}

inline int sum(int i)
{
    int ret=0;
    while(i)
    {
        ret+=b[i];
        i-=i&-i;
    }
    return ret;
}

inline void build(int k,int l,int r)
{
    tree[k].l=l;tree[k].r=r;
    if(l==r)
    {
        tree[k].sum=aa[l].val;
        return;
    }
    int mid=(l+r)>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
}

inline void prework()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]),aa[i].id=i,aa[i].val=a[i];
    sort(aa+1,aa+1+n,cmp);
    for(int i=1;i<=n;i++)
    {    
        dy[aa[i].id]=i;
        b[i]=0;
    }
    for(int i=1;i<=n;i++)
        add(i,1);
    build(1,1,n);
}

inline void upd(int k,int l)
{
    if(tree[k].l==tree[k].r)
    {
        tree[k].sum=0;
        return;
    }
    int mid=(tree[k].l+tree[k].r)>>1;
    if(l<=mid)
        upd(k<<1,l);
    else
        upd(k<<1|1,l);
    tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
}

inline int query(int k,long long res)
{
    if(tree[k].l==tree[k].r)
    {
        if(tree[k].sum>res)
            return tree[k].l-1;
        else
            return tree[k].l;
    }
    if(tree[k<<1].sum<res)
        return query(k<<1|1,res-tree[k<<1].sum);
    else
        return query(k<<1,res);
}

inline void mainwork()
{
    int l;
    for(int i=n;i>=1;i--)
    {
        upd(1,dy[i]);
        add(dy[i],-1);
        l=query(1,m-a[i]);
        ans[i]=(i-1)-sum(l);
    }
}

inline void print()
{
    for(int i=1;i<=n;i++)
        printf("%d ",ans[i]);
    puts("");
}

int main()
{
    int t;
    scanf("%d",&t);
    for(int i=1;i<=t;i++)
    {
        prework();
        mainwork();
        print();
    }
    return 0;
}
View Code

1008 Game

Unsolved.

1009 K Subsequence

https://blog.csdn.net/baiyifeifei/article/details/97706037

#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
const int maxn = 1e4;
const int inf = 0x3f3f3f3f;
struct edge {
    int to, cap, cost, rev;
    edge() {}
    edge(int to, int _cap, int _cost, int _rev) :to(to), cap(_cap), cost(_cost), rev(_rev) {}
};
int V, H[maxn + 5], dis[maxn + 5], PreV[maxn + 5], PreE[maxn + 5];
vector<edge> G[maxn + 5];
void init(int n) {
    V = n;
    for (int i = 0; i <= V; ++i)G[i].clear();
}
void AddEdge(int from, int to, int cap, int cost) {
    G[from].push_back(edge(to, cap, cost, G[to].size()));
    G[to].push_back(edge(from, 0, -cost, G[from].size() - 1));
}
int Min_cost_max_flow(int s, int t, int f, int& flow) {
    int res = 0; fill(H, H + 1 + V, 0);
    while (f) {
        priority_queue <pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>> > q;
        fill(dis, dis + 1 + V, inf);
        dis[s] = 0; q.push(pair<int, int>(0, s));
        while (!q.empty()) {
            pair<int, int> now = q.top(); q.pop();
            int v = now.second;
            if (dis[v] < now.first)continue;
            for (int i = 0; i < G[v].size(); ++i) {
                edge& e = G[v][i];
                if (e.cap > 0 && dis[e.to] > dis[v] + e.cost + H[v] - H[e.to]) {
                    dis[e.to] = dis[v] + e.cost + H[v] - H[e.to];
                    PreV[e.to] = v;
                    PreE[e.to] = i;
                    q.push(pair<int, int>(dis[e.to], e.to));
                }
            }
        }
        if (dis[t] == inf)break;
        for (int i = 0; i <= V; ++i)H[i] += dis[i];
        int d = f;
        for (int v = t; v != s; v = PreV[v])d = min(d, G[PreV[v]][PreE[v]].cap);
        f -= d; flow += d; res += d*H[t];
        for (int v = t; v != s; v = PreV[v]) {
            edge& e = G[PreV[v]][PreE[v]];
            e.cap -= d;
            G[v][e.rev].cap += d;
        }
    }
    return res;
}
int a[maxn];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,k;
        scanf("%d%d",&n,&k);
        for(register int i=1;i<=n;++i) scanf("%d",&a[i]);
        int ss=0,s=1,t=2*n+2,tt=2*n+3;
        init(tt+1);
        AddEdge(ss,s,k,0);
        AddEdge(t,tt,k,0);
        for(register int i=1;i<=n;++i)
        {
            AddEdge(s,i+1,1,0);
            AddEdge(i+1+n,t,1,0);
            AddEdge(i+1,i+1+n,1,-a[i]);
            for(register int j=i+1;j<=n;++j)
            {
                if(a[j]>=a[i])
                {
                    AddEdge(1+i+n,1+j,1,0);
                }
            }
        }
        int ans=0;
        printf("%d\n",-Min_cost_max_flow(ss,tt,inf,ans));
    }
    return 0;
}
View Code

1010 Sindar's Art Exhibition

Unsolved.

1011 Squrirrel

Unsolved.


猜你喜欢

转载自www.cnblogs.com/songorz/p/11269471.html