GYM-101853题解-第二场组队训练赛

(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦

组队训练赛第一次AK,emm,贴部分代码和简单题解吧

目录

A题Zero Array:

 离散化+数组模拟

AC代码:

#include<bits/stdc++.h>
#define mme(a,b) memset((a),(b),sizeof((a))) 
using namespace std;
typedef long long LL;
const int N = 1e6 + 7;
const int ME = 1e5 + 7;
const int mod = 998244353;
const int INF = 0x3f3f3f3f;
int n, m, q;
struct lp{
  int opt,x,y;
}op[ME];
int vis[N],ar[N],br[N],now[N];
int main(){
  int tim;
  scanf("%d",&tim);
  while(tim--){
    scanf("%d%d", &n, &q);
    mme(vis,0);int tot=0;
    for(int i=1;i<=n;++i){
      scanf("%d",&ar[i]);
      br[tot++]=ar[i];
    }
    br[tot++]=0;
    for(int i=0;i<q;++i){
      int opt,x,y;
      scanf("%d",&opt);
      op[i].opt=opt;
      if(opt==1){
        scanf("%d%d",&x,&y);
        op[i].x=x;op[i].y=y;
        br[tot++]=y;
      }
    }
    sort(br,br+tot);
    int k = unique(br,br+tot)-br,sum=0;
    for(int i=1;i<=n;++i){
      now[i]=lower_bound(br,br+k,ar[i])-br+1;
      if(now[i]==1)continue;
      vis[now[i]]++;
      if(vis[now[i]]==1)sum++;
    }
    for(int i=0;i<q;++i){
      if(op[i].opt==2){
        printf("%d\n", sum);
      }else{
        int x=op[i].x,y=op[i].y;
        if(now[x]!=1){
          vis[now[x]]--;
          if(vis[now[x]]==0)sum--;
        }
        now[x]=lower_bound(br,br+k,y)-br+1;
        if(now[x]!=1){
          vis[now[x]]++;
          if(vis[now[x]]==1)sum++;
        }
      }
    }
  }
  return 0;
}


B题New Assignment:

 素数筛+二分图最大匹配

AC代码

#include<bits/stdc++.h>
#define mme(a,b) memset((a),(b),sizeof((a))) 
using namespace std;
typedef long long LL;
const int N = 2e6 + 7;
const int ME = 1e6 + 7;
const int M = 1e4 + 7;
const int mod = 998244353;
const int INF = 0x3f3f3f3f;
int n, m, top;
int noprime[N], pcnt, p[N/2];
vector<int> have[N];
int ar[M];
bool is[M];
struct Hopcroft_Carp{
    static const int N = 20000 + 5;
    static const int M = 150000 + 5;
    static const int oo = 0x3f3f3f3f;
    int n1,n2,res,tot;
    int ddx[N],ddy[N],mx[N],my[N];
    int que[N<<1];
    bool vis[N<<1];
    int head[N<<1];
    int nex[M],u[M],v[M];
    void clear(){
        tot=-1;
        res=0;
        memset(head,-1,sizeof(head));
        memset(vis,0,sizeof(vis));
    }
    void add(int x,int y){
        u[++tot]=x;v[tot]=y;
        nex[tot]=head[x];
        head[x]=tot;
    }
    bool bfs(){
        memset(ddx,-1,sizeof(ddx));
        memset(ddy,-1,sizeof(ddy));
        res=oo;
        int rear=1,tail=1;
        for(int i=1;i<=n1;++i){
            if(mx[i]==-1){
                que[++tail]=i;ddx[i]=0;
            }
        }
        while(rear<=tail){
            int x=que[rear];
            if(ddx[x]>res)break;
            for(int i=head[x];~i;i=nex[i]){
                if(ddy[v[i]]!=-1)continue;
                ddy[v[i]]=ddx[x]+1;
                if(my[v[i]]==-1)res=ddy[v[i]];
                else {
                    ddx[my[v[i]]]=ddy[v[i]]+1;
                    que[++tail]=my[v[i]];
                }
            }
            rear++;
        }
        return res!=oo;
    }
    bool dfs(int x){
        for(int i=head[x];~i;i=nex[i]){
            if(vis[v[i]]==0&&ddy[v[i]]==ddx[x]+1){
                vis[v[i]]=1;
                if(my[v[i]]!=-1&&ddy[v[i]]==res)continue;
                if(my[v[i]]==-1||dfs(my[v[i]])){
                    my[v[i]]=x;
                    mx[x]=v[i];
                    return true;
                }
            }
        }
        return false;
    }
    int maxMatch(){
        int ans=0;
        memset(mx,-1,sizeof(mx));
        memset(my,-1,sizeof(my));
        while(bfs()){
            memset(vis,0,sizeof(vis));
            for(int i=1;i<=n1;++i){
                if(mx[i]==-1&&dfs(i))ans++;
            }
        }
        return ans;
    }
}Two;
void getprime(){
  pcnt = 0;
  memset(noprime, 0, sizeof(noprime));
  noprime[0] = noprime[1] = 1;
  for(int i = 2; i < N; ++i) {
    if(!noprime[i])p[pcnt++] = i;
    for(int j = 0; j < pcnt && i * p[j] < N; ++j) {
      noprime[i * p[j]] = 1;
      if(i % p[j] == 0)break;
    }
  }
}
void cal(int t,int id){
  int tmp = (int)sqrt(t*1.0);
  for(int i = 0; i < pcnt && p[i] <= tmp; ++i) {
    if(t % p[i] == 0) {
      have[p[i]].push_back(id);
      while (t % p[i] == 0) {
        t /= p[i];
      }
    }
    if(t == 1)break;
  }
  if(t > 1)have[t].push_back(id);
}
int main(){
  int tim;
  getprime();
  scanf("%d",&tim);
  while(tim--){
    scanf("%d", &n);
    for(int i=0;i<N-2;++i)have[i].clear();
    for(int i=1;i<=n;++i){
      scanf("%d",&ar[i]);
      cal(ar[i],i);
    }
    char s[2];
    for(int i=1;i<=n;++i){
      scanf("%s",s);
      is[i]=0;
      if(s[0]=='M')is[i]=1;
    }
    Two.clear();
    Two.n1 = n; Two.n2 = n;
    for(int i=0;i<N-2;++i){
      if(have[i].size()<=1){
        have[i].clear();
        continue;
      }
      int len = have[i].size();
      for(int j=0;j<len;++j){
        for(int k=0;k<len;++k){
          if(j==k)continue;
          if(is[have[i][j]]!=is[have[i][k]]){
            Two.add(have[i][j],have[i][k]);
          }
        }
      }
      have[i].clear();
    }
    printf("%d\n", n-Two.maxMatch()/2);
  }
  return 0;
}


C题Intersections:

 逆序对

AC代码

#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
using namespace std;
typedef long long LL;
const int N = 1e5+7;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
int n,q,tot;
int ar[N],bit[N],br[N];
void add(int x){
  while(x<=n){
    bit[x]++;
    x += lowbit(x);
  }
}
int query(int x){
  int sum=0;
  while(x){
    sum+=bit[x];
    x-=lowbit(x);
  }
  return sum;
}
int x,y;
int main(int argc, char const *argv[]){
  int tim;
  scanf("%d", &tim);
  while(tim--){
    scanf("%d", &n);
    for(int i=1;i<=n;++i){
      int x;scanf("%d",&x);
      ar[x]=i;
    }
    for(int i=1;i<=n;++i){
      int x;scanf("%d",&x);
      br[i]=ar[x];
    }
    LL all=0;
    memset(bit,0,sizeof(bit));
    for(int i=1;i<=n;++i){
      int p = br[i];
      int tmp = query(p);
      all+=tmp;
      add(p);
    }
    all=n*1LL*(n-1)/2-all;
    printf("%lld\n", all);
  }
  return 0;
}


E题Maximum Sum:

 简单状压

AC代码

#include<bits/stdc++.h>
#define mme(a,b) memset((a),(b),sizeof((a))) 
using namespace std;
typedef long long LL;
const int N = 10 + 8;
const int ME = 1<<16;
const int INF = 0x3f3f3f3f;
int n, m;
int ok[ME+1];
int dp[N][ME+1];
int ar[N][N];
inline bool adj(int x){
  return (x&(x<<1))||(x&(x>>1));
}
inline int get_num(int t,int s){
  int sum=0;
  for(int i=0;i<n;++i){
    if(s&(1<<i))sum+=ar[t][i];
  }
  return sum;
}
int main(){
    int tim;
    scanf("%d",&tim);
  while(tim--){
    scanf("%d", &n);
    memset(dp, 0, sizeof(dp));
    memset(ok,0,sizeof(ok));
    int aa = 1<<n, tot = 0;
    ///单行合法状态储存进数组
    for(int i = 0; i < aa; ++i){
      if(adj(i) == 0)ok[tot++] = i;
    }
    for(int i=0;i<n;++i){
      for(int j=0;j<n;++j){
        scanf("%d",&ar[i][j]);
      }
    }
    for(int _i = 0, i; _i < tot; ++_i){
      i = ok[_i];
      dp[0][_i]=get_num(0, i);
    }
    for(int _i = 0, i, j; _i < tot; ++_i){
      i = ok[_i];
      for(int _j = 0; _j < tot; ++_j){
        j = ok[_j];
        if((i&j)||(i&(j<<1))||(i&(j>>1)))continue;
        dp[1][_i] = max(dp[0][_j]+get_num(1,i),dp[1][_i]);
      }
    }
    for(int t = 2,i,j,k; t < n; ++t){
      for(int _i = 0; _i < tot; ++_i){
        i = ok[_i];
        for(int _j = 0; _j < tot; ++_j){
          j = ok[_j];
          if((i&j)||(i&(j<<1))||(i&(j>>1)))continue;
          dp[t][_i]=max(dp[t-1][_j]+get_num(t,i) ,dp[t][_i]);
        }
      }
    }
    int ans = 0;
    for(int _i = 0, i, j; _i < tot; ++_i){
      i = ok[_i];
      ans=max(ans,dp[n-1][_i]);
    }
    printf("%d\n", ans);
  }
  return 0;
}


G题Hard Equation:

 扩展BSGS裸题:传送门

AC代码

#include <cmath>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <climits>
#include <iostream>
#include <algorithm>
using namespace std;

typedef long long LL;
inline LL gcd(LL a, LL b) {
  return (!b) ? a : gcd(b, a % b);
}
inline void Exgcd(LL a, LL b, LL &d, LL &x, LL &y) {
  if (!b) { d = a, x = 1, y = 0; }
  else { Exgcd(b, a % b, d, y, x), y -= x * (a / b); }
}
inline LL Solve(LL a, LL b, LL c) {// ax%c=b S.T. (a,c)=1
  LL d, x, y;
  Exgcd(a, c, d, x, y);
  x = (x + c) % c;
  return x * b % c;
}
inline LL Ksm(LL x, LL y, LL p) {
  LL res = 1, t = x;
  for(; y; y >>= 1) {
    if (y & 1) res = res * t % p;
    t = t * t % p;
  }
  return res;
}

#define mod 1313131
struct Hashset {
  int head[mod], next[35010], f[35010], v[35010], ind;
  void reset() {
    ind = 0;
    memset(head, -1, sizeof head);
  }
  void Insert(int x, int _v) {
    int ins = x % mod;
    for(int j = head[ins]; j != -1; j = next[j])
      if (f[j] == x) {
        v[j] = min(v[j], _v);
        return;
      }
    f[ind] = x, v[ind] = _v;
    next[ind] = head[ins], head[ins] = ind++;
  }
  int operator [] (const int &x) const {
    int ins = x % mod;
    for(int j = head[ins]; j != -1; j = next[j])
      if (f[j] == x)
        return v[j];
    return -1;
  }
}S;

LL BSGS(LL C, LL A, LL B, LL p) {// A^x%p=B S.T.(A,p)=1
  if (p <= 100) {
    LL d = 1;
    for(int i = 0; i < p; ++i) {
      if (d == B)
        return i;
      d = d * A % p;
    }
    return -1;
  }
  else {
    int m = (int)sqrt(p);
    S.reset();
    LL d = 1, Search;
    for(int i = 0; i < m; ++i) {
      S.Insert(d, i);
      d = d * A % p;
    }
    for(int i = 0; i * m < p; ++i) {
      d = Ksm(A, i * m, p) * C % p;
      Search = S[Solve(d, B, p)];
      if (Search != -1)
        return i * m + Search;
    }
    return -1;
  }
}

int main() {
  LL x, z, k;
  register LL i, j;
  int tim;
  scanf("%d",&tim);
  while(tim--){
    scanf("%lld%lld%lld", &x, &k, &z);
    LL d = 1;
    bool find = 0;
    for(i = 0; i < 100; ++i) {
      if (d == k) {
        printf("%lld\n", i);
        find = 1;
        break;
      }
      d = d * x % z;
    }
    if (find)continue;
    LL t, C = 1, num = 0;
    bool failed = 0;
    while((t = gcd(x, z)) != 1) {
      if (k % t != 0) {
        failed = 1;
        break;
      }
      z /= t;
      k /= t;
      C = C * x / t % z;
      ++num;
    }
    LL res = BSGS(C, x, k, z);
    printf("%lld\n", res + num);
  }
  return 0;
}


K题Citations:

队友写的模拟贴个代码

AC代码

#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <cstring>
#include <cstdio>
#include <string>
#include <cmath>
#include <set>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;
typedef pair<char, int> PCI;
const LL INF = 0x3f3f3f3f;
const LL LLINF = 0x3f3f3f3f3f3f3f3f;
const int MAX_N = (int)2e5+17;
const int MAX_M = (int)2e5+17;
int N, M, S, T, K, tp;

int a[MAX_N], b[MAX_N], lt[MAX_N];
int vis[MAX_N];
char s[21][322];

int main() {
    //freopen("../data.in", "r", stdin);
    //ios_base::sync_with_stdio(false);cin.tie(0);
    //cin » T;
    scanf("%d", &T);
    int kase = 1;
    while (T--) {
        scanf("%d", &N);getchar();
        while(N--) {
            for(int i = 0; i < 10; i++) {
                fgets(s[i], sizeof(s[i]), stdin);
                //printf("%s",s[i]);
            }
            for(int i = 1; i <= 8; i++) {
                if(s[i][0]=='a') {
                    vector<char> v;v.clear();
                    for(int j = 8; ; ) {
                        v.push_back(s[i][j]);
                        v.push_back(s[i][j+1]);
                        while(s[i][j] != ' ') j++;j++;
                        v.push_back(s[i][j]);
                        while(s[i][j] != ',' && s[i][j] != '}') j++;
                        if(s[i][j] == '}') break;
                        else j += 2;
                    }
                    for(int j = 0; j < v.size(); j+=3) {
                        printf("%c%c. %c%c ",v[j],v[j+1],v[j+2],(j+3<v.size())?',':'.');
                    }
                    break;
                }

            }
            for(int i = 1; i <= 8; i++) {
                if(s[i][0]=='t') {
                    for(int j = 7; s[i][j] != '}'; j++) {
                        printf("%c",s[i][j]);
                    }
                    printf(". ");
                    break;
                }
            }
            for(int i = 1; i <= 8; i++) {
                if(s[i][0]=='j') {
                    for(int j = 9; s[i][j] != '}'; j++) {
                        printf("%c",s[i][j]);
                    }
                    printf(". ");
                    break;
                }
            }
            for(int i = 1; i <= 8; i++) {
                if(s[i][0]=='y') {
                    for(int j = 6; s[i][j] != '}'; j++) {
                        printf("%c",s[i][j]);
                    }
                    printf(";");
                    break;
                }
            }
            for(int i = 1; i <= 8; i++) {
                if(s[i][0]=='v') {
                    for(int j = 8; s[i][j] != '}'; j++) {
                        printf("%c",s[i][j]);
                    }
                    printf("(");
                    break;
                }
            }
            for(int i = 1; i <= 8; i++) {
                if(s[i][0]=='n') {
                    for(int j = 8; s[i][j] != '}'; j++) {
                        printf("%c",s[i][j]);
                    }
                    printf("):");
                    break;
                }
            }
            for(int i = 1; i <= 8; i++) {
                if(s[i][0]=='p' && s[i][1]=='a') {
                    for(int j = 7; s[i][j] != '}'; j++) {
                        printf("%c",s[i][j]);
                    }
                    printf(".\n");
                    break;
                }
            }
        }
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_39599067/article/details/81712481