2019 Multi-University Training Contest 3

时间:2023-01-03 15:38:12

Fansblog

逆元

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include <set>
#include <queue>
#define ll long long
#define ld long double
#define fo(i,l,r) for(int i = l;i <= r;i++)
#define fd(i,l,r) for(int i = r;i >= l;i--)
#define mem(x) memset(x,0,sizeof(x))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int maxn = 50050;
const int maxm = 32;
const ll inf = 1e9;
ll read() {
    ll x=0,f=1;
    char ch=getchar();
    while(!(ch>='0'&&ch<='9')) {
        if(ch=='-')f=-1;
        ch=getchar();
    };
    while(ch>='0'&&ch<='9') {
        x=x*10+(ch-'0');
        ch=getchar();
    };
    return x*f;
}
bool isp(ll p){
    ll m = sqrt(p);
    for(ll i = 2;i <= m;i++){
        if(p%i==0)return false;
    }
    return true;
}
ll q_mul(ll a,ll b,ll mod){
    ll ans = 0;
    while(b){
        if(b&1){
            b--;
            ans = (ans + a) % mod;
        }
        b>>=1;
        a = (a + a) % mod;
    }
    return ans;
}
ll qpow(ll x,ll y,ll mod){
    ll res = 1;
    while(y){
        if(y&1) res=q_mul(res,x,mod);
        x=q_mul(x,x,mod);
        y>>=1;
    }
    return res;
}
ll getans(ll t){
    ll p=2;
    for(ll i = t-1;i >= 2;i--){
        if(isp(i)){
            p=i;
            break;
        }
    }
    ll inv=0,ans=1;
    for(ll i = t-1;i >= p+1;i--){
        inv = qpow(i,t-2,t);
        if(inv <= p) ans=q_mul(ans,inv,t);
    }
    return ans;

}
int main() {
   int T;
   cin>>T;
   while(T--){
       ll a;
       a=read();
       cout<<getans(a)<<endl;
   }
    return 0;
}

Find the answer

树状数组维护,将每个插在排名对应的位置

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include <set>
#include <queue>
#define ll long long
#define ld long double
#define fo(i,l,r) for(int i = l;i <= r;i++)
#define fd(i,l,r) for(int i = r;i >= l;i--)
#define mem(x) memset(x,0,sizeof(x))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int maxn = 200050;
const int maxm = 32;
const ll inf = 1e9;
ll read() {
    ll x=0,f=1;
    char ch=getchar();
    while(!(ch>='0'&&ch<='9')) {
        if(ch=='-')f=-1;
        ch=getchar();
    };
    while(ch>='0'&&ch<='9') {
        x=x*10+(ch-'0');
        ch=getchar();
    };
    return x*f;
}
int n,m;
ll c[maxn*3],a[maxn],b[maxn],d[maxn*3];
ll lowbit(ll x){ return x&(-x);}

ll SUM(int r,ll *c){//区间查询
    ll sum=0;

    for(int i=r;i;i-=lowbit(i)) sum+=c[i];

    return sum;
}

void change(int x,ll m,ll *c){ for(int i=x;i<=n;i+=lowbit(i)) c[i]+=m;}//单点修改
struct dat{
    ll v;
    int p;
    friend bool operator < (dat a,dat b){
        return  a.v > b.v;
    }
}dats[maxn];
int main() {
   int T;
   cin>>T;
   while(T--){
       n=read();
       m=read();
       mem(c);
       mem(d);
       fo(i,1,n){
           dats[i].p=i;
           dats[i].v=read();
           a[i] = dats[i].v;
       }
       sort(dats+1,dats+1+n);
       fo(i,1,n){
           b[dats[i].p] = i;
       }
       ll sum = 0;
       fo(i,1,n){
           sum += a[i];
           int lp = 0,rp = n,mid,ans=0;
           while(lp <= rp){
               mid = (lp + rp) >> 1;
               if(sum-SUM(mid,c)<=m){
                   rp = mid - 1;
                   ans = mid;
               }else{
                   lp = mid + 1;
               }
           }
           printf("%lld ",SUM(ans,d));
           change(b[i],a[i],c);
           change(b[i],1,d);
       }
       putchar('\n');
   }
    return 0;
}

Blow up the city

支配树https://blog.csdn.net/a710128/article/details/49913553

在dag上求类似的东西,用lca即可,最后用lca统计答案

#include<bits/stdc++.h>
#define LL long long
#define MEM(x,y) memset(x,y,sizeof(x))
#define MOD(x) ((x)%mod)
#define mod 1000000007
#define pb push_back
#define STREAM_FAST ios::sync_with_stdio(false)
using namespace std;
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], G[maxn], T[maxn];
void BFS()
{
    queue<int>q;
    rt = n + 1;
    for (int i = 1; i <= n; i++) if (!deg[i]){q.push(i); E[rt].pb(i); G[i].pb(rt);}
    int tot = 0;
    while (!q.empty())
    {
        int u = q.front(); q.pop();
        a[++tot] = u;
        for (int 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];
    for (int i = 19; i >= 0; i--) if (f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
    return x == y ? x : f[x][0];
}
int main()
{
    int tt; scanf("%d", &tt);
    while (tt--)
    {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n + 1; i++) 
        {
            E[i].clear(); G[i].clear();
            T[i].clear(); 
            dep[i] = deg[i] = 0;
        }
        while (m--) 
        {
            int u, v; scanf("%d%d", &u, &v);
            E[v].pb(u); G[u].pb(v); deg[u]++;
        }
        BFS();
        dep[rt] = 1;
        for (int i = 1; i <= n; i++)
        {
            int u = a[i], fa = -1;
            for (int v : G[u]) fa = (fa == -1 ? v : LCA(fa, v));
            dep[u] = dep[fa] + 1; f[u][0] = fa; T[fa].pb(u);
            for (int i = 1; i <= 19; i++) f[u][i] = f[f[u][i - 1]][i - 1];
        }
        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;
}

Distribution of books

二分+dp,检验的时候用线段树求特定范围最大值

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include <set>
#include <queue>
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fo(i,l,r) for(int i = l;i <= r;i++)
#define mem(x) memset(x,0,sizeof(x))
using namespace std;
const int maxn = 200050;
const ll inf = 1e9;
ll read() {
    ll x=0,f=1;
    char ch=getchar();
    while(!(ch>='0'&&ch<='9')) {
        if(ch=='-')f=-1;
        ch=getchar();
    };
    while(ch>='0'&&ch<='9') {
        x=x*10+(ch-'0');
        ch=getchar();
    };
    return x*f;
}
int n,m,k;
int rt;
ll Max[maxn<<2];
ll a[maxn],b[maxn],c[maxn],d[maxn];
void pushup(int rt){
    Max[rt] = max(Max[rt<<1],Max[rt<<1|1]);
}
void addval(int p,ll v,int l,int r,int rt){
    if(l == r){
        Max[rt] = v;
        return;
    }
    int m = (l+r)>>1;
    if(p <= m) addval(p,v,lson);
    else addval(p,v,rson);
    pushup(rt);
}
ll query_max(int L,int R,int l,int r,int rt){
    if(L <= l && r <= R){

        return Max[rt];
    }
    int m = (l+r)>>1;
    ll ret = -inf;
    if(L <= m) ret = max(ret,query_max(L,R,lson));
    if(R > m) ret = max(ret,query_max(L,R,rson));
    return ret;
}
struct dat{
    ll v;
    int p;
    friend bool operator < (dat a,dat b){
        if(a.v!=b.v)return a.v < b.v;
        else return a.p > b.p;
    }
}dats[maxn];
bool check(ll t){
    mem(c);
    int sz = maxn<<2;
    fo(i,0,sz-1)Max[i] = -inf*(ll)maxn;
    addval(b[0]+1,0,1,n+1,1);
    fo(i,1,n){
        int p = lower_bound(d,d+1+n,dats[b[i]].v-t) - d;
        if(p > n)continue;
        ll now = query_max(p+1,n+1,1,n+1,1)+1;
        addval(b[i]+1,now,1,n+1,1);
        if(now >= k) return true;
    }
    return false;

}
int main() {
    int T;
    cin>>T;
    while(T--){
        n=read();
        k=read();
        fo(i,1,n){
            a[i]=read();
            c[i] = c[i-1]+a[i];
            dats[i].v = c[i];
            dats[i].p = i;
        }
        dats[0].v=dats[0].p=0;
        sort(dats,dats+1+n);
        m = 0;
        fo(i,0,n){
            b[dats[i].p] = i;
            d[i] = dats[i].v;
        }
        ll lp = (ll)maxn*(-inf),rp = (ll)maxn*inf,mid,ans;
        while(lp <= rp){
            mid = (lp + rp) >> 1;
            if(check(mid)){
                ans = mid;
                rp = mid - 1;
            }else{
                lp = mid + 1;
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}