2023 China Collegiate Programming Contest (CCPC) Guilin Onsite (The 2nd Universal Cup. Stage 8: Guilin)

题解:

https://files.cnblogs.com/files/clrs97/2023Guilin_Tutorial.pdf

 

Code:

A. Easy Diameter Problem

#include<bits/stdc++.h>
using namespace std;
const int N = 300 ;
const int mod = 1e9 + 7;
typedef pair<int,int> pii;
vector<pair<int,int> > E[N + 5];
int t[N*2 + 5 ] , rt[ N*2 + 5];
int fpow(int a,int b)
{
    int ans = 1;
    while(b) {
        if(b & 1) ans = 1LL*ans*a%mod;
        a = 1LL*a*a%mod;b >>= 1;
    }
    return ans;
}
 
int n ;
vector<vector<int> > f[N / 2][N * 2] ; ///长度,中心所在点,完整子树标号,可以放置的节点L个
void upd(int &x,int y)
{
    ((x += y) >= mod ? (x -= mod) : 0) ;
}
void upd(int i,int j,int k,int l,int y)
{
    // if(i==0&&j==10) printf("%d %d %d %d , %d\n",i,j,k,l,y) ;
    if(f[i][j].size() <= k) f[i][j].resize(k + 1) ;
    if(f[i][j][k].size() <= l) f[i][j][k].resize(l + 1) ;
    upd(f[i][j][k][l] , y) ;
    return ;
}
int C(int a,int b)
{
    if(a < b) return 0;
    return 1LL * t[a] * rt[b] % mod * rt[a - b] % mod;
}
int Cm(int a,int b)
{
    if(a == 0 && b == 0) return 1;
    return C(a + b - 1 ,b);
}
int put(int n,int k)  ///n个位置,可重,有序地放入k个物品
{
    return 1LL*C(n + k - 1 , k)*t[k] % mod;
}
vector<int> num[N + 5][N + 5] ; ///i号点,深度为j,0~size方向的子树大小,最后一位代表总大小
pii edges[N + 5]; ///边
int be[N + 5][2] ; ///边在vector中的id(.first , .second)
void calc(int i,int j,int k,int l) ///长度,中心所在点,完整子树标号,可以放置的节点L个
{
    int ca ;
    if(k != -1 ) ca = f[i][j][k][l] ;
    else ca = 1;
    // if(k == -1) printf("MID %d\n", j );
    // printf("Ans %d %d %d %d , %d\n",i,j,k,l,ca) ;
    // if(j <= n && k != -1) printf("Sub %d\n" , E[j][k]) ;
    // else if(k != -1) printf("Sub point %d %d\n" , edges[j - n].first , edges[j - n].second) ;
    if(j <= n) {
        int cnt = 0;
        for(auto [v,id] : E[j]) {
            if(cnt == k) {
                int other_cnt = num[j][i].back() - num[j][i][cnt] ;
                for(int m = 1; m <= other_cnt ; m++) {
                    upd(i - 1 ,id + n , edges[id].second == j , m , 1LL * ca * Cm(l , other_cnt - m) % mod * t[other_cnt] % mod) ;
                }
            }
            else {
                int other , ne ;
                if(k != -1) {
                    other = num[j][i].back()-num[j][i][cnt]-num[j][i][k];
                    ne = num[j][i][k] ;
                }
                else {
                    other = num[j][i].back() - num[j][i][cnt] ;
                    ne = 0;
                }
                upd(i - 1 , id + n , edges[id].second == j , l + other + ne, 1LL * ca * t[ne] % mod * Cm(l + ne + 1, other) % mod * t[other] % mod) ;
            }
            cnt++;
        }
    }
    else {
        // puts("injbk") ;
        for(int cnt = 0;cnt < 2;cnt++) {
            int to_id , ano_id;
            if(cnt == 0) to_id = edges[j - n].first , ano_id = edges[j - n].second;
            else to_id = edges[j - n].second , ano_id = edges[j - n].first;
            // printf("CNT %d\n" , cnt) ;
            if(cnt == k) {
                int other = num[ano_id][i].back() - num[ano_id][i][be[j - n][cnt ^ 1]] ;
                for(int m = 1;m <= other;m++) {
                    upd(i , to_id , be[j - n][cnt] , m , 1LL * ca * Cm(l , other - m) % mod * t[other] % mod) ;
                }
            }
            else {
                // printf("%d %d , %d %d\n",ano_id , i , num[ano_id][i].size() , be[j - n][cnt]) ;
                int ne = num[ano_id][i].back() - num[ano_id][i][be[j - n][cnt ^ 1]] ;
                // puts("OK") ;
                // printf("%d goto  %d , %d , %d\n",j,to_id,be[j][cnt] , E[to_id][be[j][cnt]]) ;
                upd(i , to_id , be[j - n][cnt] , l + ne , 1LL * ca * t[ne] % mod );
            }
            // printf("CNT %d\n" , cnt) ;
        }
    }
}
 
int dis[N + 5];
int bfs(int u)
{
    for(int i = 1;i <= n;i++) dis[i] = 1e9;
    dis[u] = 1;
    queue<int> q;q.push(u) ;
    while(q.size()) {
        int x = q.front() ; q.pop() ;
        for(auto [v,w] : E[x]) {
            if(dis[v] > dis[x] + 1) {
                dis[v] = dis[x] + 1;
                q.push(v) ;
            }
        }
    }
    int mx = 1;
    for(int i = 2;i <= n;i++) {
        if(dis[i] > dis[mx]) mx = i;
    }
    return mx;
}
vector<int> nodes ;
bool dfs(int fa,int u,int v)
{
    if(u == v) {
        nodes.push_back(v) ; return 1;
    }
    for(auto [x,w] : E[u]) {
        if(x != fa) {
            if(dfs(u , x , v)) {
                nodes.push_back(u) ; return 1;
            }
        }
    }
    return 0;
}
int siz[N + 5][N + 5];
void dfs_s(int fa,int u)
{
    siz[u][0] = 1;
    for(auto [v,w] : E[u]) {
        if(v != fa) {
            dfs_s(u , v) ; 
            for(int l = 1;l <= n && siz[v][l - 1];l++) {
                siz[u][l] += siz[v][l - 1] ;
            }
        }
    }
}
int main()
{
    ios::sync_with_stdio(false) ; cin.tie(0) ;
    cin >> n;
    if(n <= 3) {
        cout << fpow(2 , n - 1) << '\n' ; return 0;
    }
    map<pii,int> mp;
    for(int i = 1;i < n;i++) {
        int u , v;cin >> u >> v;
        E[u].push_back({v , i}) ; E[v].push_back({u , i}) ;
        mp[{u , v}] = mp[{v , u}] = i;
        edges[i] = {u , v} ;
        be[i][0] = E[u].size() - 1;
        be[i][1] = E[v].size() - 1;
    }
    t[0] = rt[0] = 1;
    for(int i = 1;i <= n*2 + 1;i++) t[i] = 1LL*t[i - 1]*i % mod, rt[i] = fpow(t[i] , mod - 2) ;
    int u = bfs(1) ;
    int v = bfs(u) ;
    dfs(0 , u , v);
    for(int i = 1;i <= n;i++) {
        memset(siz,0,sizeof(siz)) ;
        dfs_s(0 , i) ;
        for(int j = 0; siz[i][j] && j <= n; j++) {
            num[i][j].resize(E[i].size() + 1) ;
            if(j) {
                for(int k = 0;k < E[i].size();k++) num[i][j][k] = siz[E[i][k].first][j - 1] ;
            }
            num[i][j].back() = siz[i][j] ;
        }
    }
    int L ; 
    if(nodes.size() & 1) {
        calc( nodes.size() / 2 ,nodes[nodes.size() / 2] , -1 , 0) ;
    }
    else {
        calc(nodes.size() / 2 - 1 ,n + mp[{nodes[nodes.size() / 2] , nodes[nodes.size()/2 - 1]}] ,  -1 , 0) ;
    }
    // puts("OJBK") ;
    for(int i = nodes.size()/2 - 1; i >= 1; i--) {
        for(int j = n + n - 1;j >= 1;j--) {
            for(int k = 0;k < f[i][j].size();k++) {
                for(int l = 0;l < f[i][j][k].size();l++) {
                    if(f[i][j][k][l]) calc(i , j , k , l) ;
                }
            }
        }
    }
    int ans = 0;
    for(int j = n + 1 ; j <= n*2 - 1 ; j++) {
        for(int k = 0 ; k < 2 && k < f[0][j].size();k++) {
            for(int l = 0;l < f[0][j][k].size();l++) {
                ans = (ans + 1LL * f[0][j][k][l] * 2) % mod ;
                //  printf("F %d %d %d , %d\n",j,k,l,f[0][j][k][l]) ;
            }
        }
    }
    cout << ans << '\n' ;
    return 0;
}

  

B. The Game

#include<bits/stdc++.h>
using namespace std;
int n , m;
int a[300005] , b[300005];
typedef long long ll;
void solv()
{
    cin >> n >> m;
    for(int i = 1;i <= n;i++) cin >> a[i] ;
    for(int i = 1;i <= m;i++) cin >> b[i] ;
    sort(a + 1 , a + n + 1) ;
    sort(b + 1 , b + m + 1) ;
    ll sum = 0;
    for(int i = m;i >= 1;i--) {
        if(a[n-(m-i)] > b[i]) {
            cout << -1 << '\n' ; return ;
        }
        sum += (b[i] - a[n-(m-i)]) ;
    }
    if(sum > n - m) {
        cout << -1 << '\n' ; return ;
    }
    vector<int> ans;
    int ndel = (n - m) - sum;
    multiset<int> st;
    for(int i = 1;i <= n;i++) st.insert(a[i]) ;
    // int cb1 = 0;
    // for(int i = 1;i <= m;i++) cb1 += (b[i] == b[1]) ;
 
    while(ndel > 0) {
        for(int i = 1;i <= ndel;i++) {
            int x = *st.begin();
            ans.push_back(x) ;
            st.erase(st.begin()) ; st.insert(x + 1) ;
            st.erase(st.begin()) ;
        }
        vector<int> a(st.begin() , st.end()) ;
        sum = 0;
        for(int i = a.size() - m;i < a.size();i++) {
            if(a[i] > b[i - (a.size()-m) + 1]) {
                cout << -1 << '\n' ; return ;
            }
            sum += b[i - (a.size()-m) + 1] - a[i] ;
        }
        ndel = (a.size() - m) - sum ;
    }
    vector<int> a(st.begin() , st.end()) ;
    sum = 0;
    for(int i = a.size() - m;i < a.size();i++) {
        if(a[i] > b[i - (a.size()-m) + 1]) {
            cout << -1 << '\n' ; return ;
        }
        int t = (i - (a.size()-m)+1) ;
        while(a[i] < b[t]) {
            ans.push_back(a[i]) ; a[i]++;
        }
    }
    
    cout << ans.size() << '\n' ;
    for(auto &x : ans) cout << x <<' ' ;
    cout << '\n';
}
int main()
{
    // freopen("in.txt","r",stdin) ;
    ios::sync_with_stdio(false) ; cin.tie(0) ; cout.tie(0) ;
    int t;cin >> t;
    while(t--) solv() ;
}

  

C. Master of Both IV

#include<bits/stdc++.h>
using namespace std;
 
const int N=2e5+1e3+7,P=998244353;
 
int T,a[N],n,c[N];
 
struct LB{
    int a[21];
 
    void clear()
    {
        memset(a,0,sizeof(a));
    }
 
    int ins(int x)
    {
        for(int i=20;i>=0;i--)
        {
            if(!(x>>i&1))
                continue;
            if(!a[i])
            {
                a[i]=x;
                return 1;
            }
            else
                x^=a[i];
        }
        return 0;
    }
}e;
 
vector<int> fac[N];
 
int pw[N];
 
int main()
{
    pw[0]=1;
    for(int i=1;i<=200000;i++)
        pw[i]=pw[i-1]*2%P;
    for(int i=1;i<=200000;i++)
        for(int j=i*2;j<=200000;j+=i)
            fac[j].push_back(i);
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            c[i]=0;
        e.clear();
        int f=0;
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]),c[a[i]]++,f+=!e.ins(a[i]);
        int ans=pw[f]-1;
        for(int i=1;i<=n;i++)
        {
            if(!c[i])
                continue;
            int f=0;
            e.clear();
            for(auto j:fac[i])
            {
                if(!c[j])
                    continue;
                f+=!e.ins(j);
                f+=c[j]-1;
            }
            ans=(ans+pw[f+c[i]-1])%P;
        }
        printf("%d\n",ans);
    }
}

  

D. Subway

#include<bits/stdc++.h>
using namespace std;
const int B=10001,hf=5001;//+(-1,hf),+(-k*2,k*B)
int main()
{
	int n;
	cin>>n;
	vector<tuple<int,int,int>> a(n+5);
	int maxa=0;
	for(int i=1;i<=n;i++)
	{
		int x,y,c;
		cin>>x>>y>>c;
		maxa=max(maxa,c);
		a[i]={x,y,c};
	}
	sort(a.begin()+1,a.begin()+n+1);
	vector<vector<pair<int,int>>> lines(maxa);
	for(int k=0;k<maxa;k++)
	{
		for(int i=1;i<=n;i++)
		{
			auto [x,y,c]=a[i];
			if(k<c)
			{
				lines[k].emplace_back(x,y);
			}
			lines[k].emplace_back(x-1-k*2,y+hf+k*B);
		}
	}
	cout<<lines.size()<<endl;
	for(auto &line:lines)
	{
		cout<<line.size();
		for(auto [x,y]:line)cout<<' '<<x<<' '<<y;
		cout<<endl;
	}
	return 0;
}

  

E. Prefix Mahjong

#include <bits/stdc++.h>
using namespace std;
constexpr int magic = 18;
 
struct Matrix {
  array<unsigned, magic> r;
  Matrix() { r.fill(0); }
};
Matrix operator*(const Matrix &lhs, const Matrix &rhs) {
  Matrix res;
  for (int i = 0; i < 9; i += 1) {
    if (lhs.r[i]) {
      for (int j = 0; j < 9; j += 1) {
        if ((lhs.r[i] >> (j + 9)) % 2) { res.r[i] |= rhs.r[j]; }
        if ((lhs.r[i] >> j) % 2) { res.r[i] |= rhs.r[j] >> 9; }
      }
    }
  }
  return res;
}
int main() {
  cin.tie(nullptr)->sync_with_stdio(false);
  array<Matrix, magic> base;
  for (int i = 0; i < magic; i += 1) {
    for (int x = 0; x < magic; x += 1) {
      for (int y = 9; y < magic; y += 1) {
        int x0 = x % 3, x1 = x / 3 % 3, x2 = x / 9;
        int y0 = y % 3, y1 = y / 3 % 3, y2 = y / 9;
        if (y2 < x2) { continue; }
        if (x0 != y1) { continue; }
        int k = (y2 > x2 ? 2 : 0) + (x1 + x0 + y0);
        if (i >= k and (i - k) % 3 == 0) { base[i].r[y - 9] |= 1 << x; }
      }
    }
  }
  int t;
  cin >> t;
  for (int ti = 0; ti < t; ti += 1) {
    int n;
    cin >> n;
    set<int> s;
    vector<int> p(n);
    for (int &pi : p) {
      cin >> pi;
      s.insert(pi);
      s.insert(pi + 1);
    }
    int m = 0;
    map<int, int> mp;
    for (int x : s) { mp[x] = m++; }
    for (int &pi : p) { pi = mp[pi]; }
    int k = 1;
    while (k < m) { k <<= 1; }
    vector<Matrix> seg(k << 1, base[0]);
    vector<int> c(m);
    for (int pi : p) {
      c[pi] += 1;
      while (c[pi] >= magic) { c[pi] -= 3; }
      int i = pi + k;
      seg[i] = base[c[pi]];
      for (i /= 2; i; i /= 2) { seg[i] = seg[i * 2] * seg[i * 2 + 1]; }
      cout << seg[1].r[0] % 2;
    }
    cout << "\n";
  }
}

  

F. Redundant Towers

#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
typedef pair<int,int>E;
const int N=100005,M=215;
int n,k,q,i,j,x,L,R,last,at[N],pos[N];bool adj[N][9];
struct P{int x,y,id;bool on;}p[N];
struct Node{
  int predeg,w,ori;
  Node(){}
  Node(int _predeg,int _w,int _ori){
    predeg=_predeg;
    w=_w;
    ori=_ori;
  }
};
struct Graph{
  int leaf,n;
  vector<Node>nodes;
  vector<E>edges;
}val[262155];
namespace Solver{
int n,nowleaf;
int predeg[M],w[M],ori[M],isvip[M];
int g[M],v[M],nxt[M],ed;
int deg[M],dfn[M],low[M],q[M],t,num,sub,all;
int ct,cv,newid[M];
int _g[M],_v[M],_nxt[M],_ed;
int G[M],V[M],NXT[M],ED;
int fa[M],dep[M],id[M];
Node tree[M];
inline void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
inline void ADD(int x,int y){
  deg[y]++;
  V[++ED]=y;
  NXT[ED]=G[x];
  G[x]=ED;
  V[++ED]=x;
  NXT[ED]=G[y];
  G[y]=ED;
}
void tarjan(int x,int f){
  dfn[x]=low[x]=++num;
  q[++t]=x;
  for(int i=g[x];i;i=nxt[i])if(!dfn[v[i]]){
    int y=v[i];
    tarjan(y,x);
    if(low[x]>low[y])low[x]=low[y];
    if(!f)sub++;
    if(dfn[x]<=low[y]&&f||!f&&sub>1){
      ADD(++all,x);
      while(1){
        int z=q[t--];
        ADD(all,z);
        if(z==y)break;
      }
    }
  }else if(low[x]>dfn[v[i]])low[x]=dfn[v[i]];
}
inline void addedge(int x,int y){
  if(x>0)swap(x,y);
  x*=-1;
  _v[++_ed]=y;
  _nxt[_ed]=_g[x];
  _g[x]=_ed;
}
void dfs(int x,int y){
  int d=0;
  dep[x]=dep[y]+1;
  fa[x]=y;
  for(int i=G[x];i;i=NXT[i]){
    int u=V[i];
    if(u==y)continue;
    dfs(u,x);
    if(!id[u]){
      if(x<=n)predeg[x]++;
    }else{
      d++;
      id[x]^=id[u];
    }
  }
  if(!d&&(x>n||!isvip[x])){
    if(x<=n&&deg[x]+predeg[x]<=1)nowleaf+=w[x];
    return;
  }
  if(d<2&&(x>n||!isvip[x]))return;
  id[x]=x;
  if(x<=n){
    tree[++ct]=Node(predeg[x],w[x],ori[x]);
    newid[x]=ct;
  }else{
    cv++;
    newid[x]=-cv;
  }
  int X=newid[x];
  for(int i=G[x];i;i=NXT[i]){
    int u=V[i];
    if(u==y)continue;
    int t=id[u];
    if(!t)continue;
    int len=dep[t]-dep[x];
    int Y=newid[t];
    if(len==1){
      addedge(X,Y);
    }else if(len==2){
      if(x<=n){
        //X-O-X
        cv++;
        addedge(X,-cv);
        addedge(-cv,Y);
      }else{
        int mid=fa[t];
        if(predeg[mid]){
          //O-X-O
          //  |
          tree[++ct]=Node(0,0,0);
        }else{
          //O-X-O
          tree[++ct]=Node(0,w[mid],0);
        }
        addedge(X,ct);
        addedge(ct,Y);
      }
    }else{
      int sum=0;
      for(int j=fa[t];j!=x;j=fa[j])if(j<=n&&!predeg[j])sum+=w[j];
      if(len&1){
        cv++;
        tree[++ct]=Node(0,sum,0);
        addedge(ct,-cv);
        if(x<=n){
          //X-O-X-O
          //X-O-X-O-X-O-...
          addedge(X,-cv);
          addedge(ct,Y);
        }else{
          //O-X-O-X
          //O-X-O-X-O-X-...
          addedge(X,ct);
          addedge(-cv,Y);
        }
      }else{
        if(x<=n){
          //X-O-X-O-X
          //X-O-X-O-X-O-X...
          cv+=2;
          tree[++ct]=Node(0,sum,0);
          addedge(X,-cv+1);
          addedge(-cv+1,ct);
          addedge(ct,-cv);
          addedge(-cv,Y);
        }else{
          //O-X-O-X-O
          //O-X-O-X-O-X-O...
          tree[++ct]=Node(0,sum,0);
          addedge(X,ct);
          addedge(ct,Y);
        }
      }
    }
  }
}
inline void compress(Graph&res){
  int i;
  all=n;
  num=0;
  for(i=1;i<=n;i++){
    dfn[i]=0;
    deg[i]=0;
  }
  for(i=1;i<=n;i++)if(!dfn[i]){
    sub=0;
    t=0;
    tarjan(i,0);
    if(t>1){
      all++;
      while(t)ADD(all,q[t--]);
    }
  }
  ct=cv=0;
  _ed=0;
  for(i=1;i<=n;i++){
    if(!isvip[i])continue;
    if(dep[i])continue;
    dfs(i,0);
  }
  for(i=1;i<=n;i++){
    if(dep[i])continue;
    if(deg[i]+predeg[i]<=1)nowleaf+=w[i];
  }
  res.edges.clear();
  for(i=1;i<=cv;i++){
    int last=0,st=0,len=0;
    for(int j=_g[i];j;j=_nxt[j]){
      int o=_v[j];
      if(!st)st=o;else res.edges.push_back(E(last,o));
      last=o;
      len++;
    }
    if(len>2)res.edges.push_back(E(st,last));
    _g[i]=0;
  }
  ED=0;
  for(i=1;i<=all;i++){
    G[i]=0;
    dep[i]=0;
    id[i]=0;
  }
  res.leaf=nowleaf;
  res.n=ct;
  res.nodes.resize(ct+1);
  for(i=1;i<=ct;i++)res.nodes[i]=tree[i];
}
inline void init(Graph&graph,int x){
  graph.leaf=0;
  graph.edges.clear();
  if(!p[x].on){
    graph.n=0;
    graph.nodes.clear();
  }else{
    graph.n=1;
    graph.nodes.resize(2);
    graph.nodes[1]=Node(0,1,x);
  }
}
inline void merge(int o,int l,int mid,int r){
  const Graph&A=val[o<<1];
  const Graph&B=val[o<<1|1];
  nowleaf=A.leaf+B.leaf;
  int ca=A.n,cb=B.n,i;
  n=ca+cb;
  for(i=1;i<=ca;i++){
    predeg[i]=A.nodes[i].predeg;
    w[i]=A.nodes[i].w;
    ori[i]=A.nodes[i].ori;
  }
  for(i=1;i<=cb;i++){
    predeg[i+ca]=B.nodes[i].predeg;
    w[i+ca]=B.nodes[i].w;
    ori[i+ca]=B.nodes[i].ori;
  }
  for(i=1;i<=n;i++)pos[ori[i]]=i;
  ed=0;
  for(i=1;i<=n;i++)isvip[i]=g[i]=0;
  for(vector<E>::const_iterator it=A.edges.begin();it!=A.edges.end();it++){
    add(it->first,it->second);
    add(it->second,it->first);
  }
  for(vector<E>::const_iterator it=B.edges.begin();it!=B.edges.end();it++){
    add(it->first+ca,it->second+ca);
    add(it->second+ca,it->first+ca);
  }
  for(i=l;i<=r&&i-l<=k;i++){
    int x=pos[i];
    if(x)isvip[x]=1;
  }
  for(i=r;i>=l&&r-i<=k;i--){
    int x=pos[i];
    if(x)isvip[x]=1;
  }
  for(i=mid+1;i<=r&&i-mid-1<=k;i++){
    int x=pos[i];
    if(!x)continue;
    for(int j=max(l,i-k);j<=mid;j++){
      if(!adj[i][i-j])continue;
      int y=pos[j];
      if(!y)continue;
      add(x,y);
      add(y,x);
    }
  }
  for(i=1;i<=n;i++)pos[ori[i]]=0;
  compress(val[o]);
}
}
namespace Tarjan{
int n,pre[M],w[M],g[M],v[M],nxt[M],ed;
int dfn[M],low[M],q[M],num,t,sub,notcut;
inline void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
void tarjan(int x,int f){
  dfn[x]=low[x]=++num;
  q[++t]=x;
  bool iscut=0;
  for(int i=g[x];i;i=nxt[i])if(!dfn[v[i]]){
    int y=v[i];
    tarjan(y,x);
    if(low[x]>low[y])low[x]=low[y];
    if(!f)sub++;
    if(dfn[x]<=low[y]&&f||!f&&sub>1){
      iscut=1;
      while(1){
        int z=q[t--];
        if(z==y)break;
      }
    }
  }else if(low[x]>dfn[v[i]])low[x]=dfn[v[i]];
  if(!iscut){
    int deg=!!g[x];
    deg+=pre[x];
    if(deg<=1)notcut+=w[x];
  }
}
inline int cal(const Graph&graph){
  notcut=graph.leaf;
  n=graph.n;
  int i;
  for(i=1;i<=n;i++){
    pre[i]=graph.nodes[i].predeg;
    w[i]=graph.nodes[i].w;
    g[i]=dfn[i]=0;
  }
  ed=0;
  for(vector<E>::const_iterator it=graph.edges.begin();it!=graph.edges.end();it++){
    add(it->first,it->second);
    add(it->second,it->first);
  }
  for(i=1;i<=n;i++)if(!dfn[i]){
    sub=0;
    t=0;
    tarjan(i,0);
  }
  return notcut;
}
}
inline bool cmp(const P&A,const P&B){return A.x<B.x;}
inline long long mysqr(int x){return 1LL*x*x;}
inline bool check(const P&A,const P&B){
  return mysqr(A.x-B.x)+mysqr(A.y-B.y)<=mysqr(k);
}
void build(int x,int a,int b){
  if(a==b){
    Solver::init(val[x],a);
    return;
  }
  int mid=(a+b)>>1;
  build(x<<1,a,mid);
  build(x<<1|1,mid+1,b);
  Solver::merge(x,a,mid,b);
}
void change(int x,int a,int b,int c){
  if(a==b){
    Solver::init(val[x],a);
    return;
  }
  int mid=(a+b)>>1;
  if(c<=mid)change(x<<1,a,mid,c);else change(x<<1|1,mid+1,b,c);
  Solver::merge(x,a,mid,b);
}
int main(){
  scanf("%d%d",&n,&k);
  for(i=1;i<=n;i++){
    scanf("%d%d",&p[i].x,&p[i].y);
    p[i].id=i;
    p[i].on=1;
  }
  sort(p+1,p+n+1,cmp);
  for(i=1;i<=n;i++)at[p[i].id]=i;
  for(i=1;i<=n;i++)for(j=max(i-k,1);j<i;j++)if(check(p[i],p[j]))adj[i][i-j]=1;
  build(1,1,n);
  scanf("%d",&q);
  last=0;
  while(q--){
    scanf("%d",&x);x^=last;
    x=at[x];
    p[x].on^=1;
    change(1,1,n,x);
    last=Tarjan::cal(val[1]);
    printf("%d\n",last);
  }
}

  

G. Hard Brackets Problem

#include<bits/stdc++.h>
using namespace std;
 
const int N=2e5+1e3+7,P=998244353;
 
int T;
 
string s;
 
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>T;
    while(T--)
    {
        cin>>s;
        int mn=0,f=0;
        for(int i=(int)s.size()-1;i>=0;i--)
        {
            if(s[i]==')')
                f++;
            else
                f--;
            mn=min(mn,f);
        }
        if(mn<0)
            cout<<"impossible\n";
        else
            cout<<s<<"\n";
    }
}

  

H. Sweet Sugar

#include<cstdio>
#define rep(i) for(int i=0;i<2;i++)
const int N=1000005,inf=100000000;
int Case,n,m,i,x,y,w[N],g[N],v[N<<1],nxt[N<<1],ed,ans,f[N][2],h[2];bool cut[N];
inline void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
inline void up(int&a,int b){a<b?(a=b):0;}
void dfs(int x,int y){
	rep(j)f[x][j]=-inf;
	f[x][w[x]&1]=w[x];
	for(int i=g[x];i;i=nxt[i]){
		int u=v[i];
		if(u==y)continue;
		dfs(u,x);
		if(cut[u])continue;
		rep(j)h[j]=f[x][j];
		rep(j)rep(k)up(h[j^k],f[x][j]+f[u][k]);
		rep(j)f[x][j]=h[j];
	}
	if(f[x][m&1]>=m)cut[x]=1,ans++;
}
int main(){
	scanf("%d",&Case);
	while(Case--){
		scanf("%d%d",&n,&m);
		for(i=1;i<=n;i++)scanf("%d",&w[i]);
		for(i=1;i<n;i++)scanf("%d%d",&x,&y),add(x,y),add(y,x);
		dfs(1,0);
		printf("%d\n",ans);
		for(ed=ans=i=0;i<=n;i++)g[i]=cut[i]=0;
	}
}

  

I. Barkley II

#include<bits/stdc++.h>
using namespace std;
 
const int N=5e5+1e3+7,P=998244353;
 
int T,a[N],n,m;
 
struct DS{
 
    int c[N];
 
    void clear()
    {
        fill(c+1,c+n+1,0);
    }
 
    void add(int x,int v)
    {
        while(x)
        {
            c[x]+=v;
            x-=x&-x;
        }
    }
 
    int qry(int x)
    {
        int ret=0;
        while(x<=n)
        {
            ret+=c[x];
            x+=x&-x;
        }
        return ret;
    }
}col;
 
int la[N],b[N],ls[N];
 
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        m=min(m,n);
        m++;
        vector<int> X;
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]),X.push_back(a[i]);
        sort(X.begin(),X.end());
        for(int i=1;i<=n;i++)
            b[i]=lower_bound(X.begin(),X.end(),a[i])-X.begin()+1;
        fill(la+1,la+n+2,0);
        fill(ls+1,ls+n+2,0);
        col.clear();
        int ans=-1;
        for(int i=1;i<=n;i++)
        {
            if(a[i]<=n+1)
                ls[a[i]]=i;
            int L=la[b[i]]+1;
            int R=i-1;
            if(i!=1)
                ans=max(ans,col.qry(L)-X[b[i]-1]);
            if(la[b[i]])
                col.add(la[b[i]],-1);
            col.add(i,1);
            la[b[i]]=i;
        }
        for(int i=1;i<=n+1;i++)
            ans=max(ans,col.qry(ls[i]+1)-i);
        printf("%d\n",ans);
    }
}

  

J. The Phantom Menace

#include<bits/stdc++.h>
using namespace std;
 
using ull=unsigned long long;
 
using pii=pair<int,int>;
 
const int N=4e6+1e3+7;
 
constexpr uint64_t P = (1ull<<61) - 1, bs = 1313131;
 
uint64_t mul(uint64_t a, uint64_t b){
	uint64_t l1 = (uint32_t)a, h1 = a>>32, l2 = (uint32_t)b, h2 = b>>32;
	uint64_t l = l1*l2, m = l1*h2 + l2*h1, h = h1*h2;
	uint64_t ret = (l&P) + (l>>61) + (h << 3) + (m >> 29) + (m << 35 >> 3) + 1;
	ret = (ret & P) + (ret>>61);
	ret = (ret & P) + (ret>>61);
	return ret-1;
}
 
ull add(const ull &a, const ull &b) {
    return a + b >= P ? a + b - P : a + b;
}
 
ull pw[N];
 
ull geth(const vector<ull> &h,int l,int r)
{
    return add(h[r],P-mul(h[l-1],pw[r-l+1]));
}
 
int T,n,m;
 
string s[N],t[N];
 
namespace Graph {
    int n;
 
    vector<pii> g[N];
 
    vector<int> st;
 
    int in[N],use[N];
 
    void dfs(int x)
    {
        while(use[x]<g[x].size())
        {
            auto [v,id]=g[x][use[x]];
            use[x]++;
            dfs(v);
            st.push_back(id);
        }
    }
 
    vector<int> Euler()
    {
        fill(in,in+n,0);
        fill(use,use+n,0);
        for(int i=0;i<n;i++)
            for(auto [v,id]:g[i])
                in[v]++;
        for(int i=0;i<n;i++)
            if(in[i]!=g[i].size())
                return {};
        for(int i=0;i<n;i++)
            if(g[i].size())
            {
                st.clear();
                dfs(i);
                reverse(st.begin(),st.end());
                return st;
            }
        return {};
    }
}
 
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>T;
    unordered_map<ull,int>pre,suf;
    while(T--)
    {
        cin>>n>>m;
        pw[0]=1;
        for(int i=1;i<=m;i++)
            pw[i]=mul(pw[i-1],bs);
        for(int i=1;i<=n;i++)
        {
            cin>>s[i];
            s[i]=' '+s[i];
        }
        for(int i=1;i<=n;i++)
        {
            cin>>t[i];
            t[i]=' '+t[i];
        }
        vector<vector<ull> >hs(n+1,vector<ull>(m+1)),ht(n+1,vector<ull>(m+1));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                hs[i][j]=add(mul(hs[i][j-1],bs),s[i][j]),ht[i][j]=add(mul(ht[i][j-1],bs),t[i][j]);
        bool ok=0;
        for(int t=0;t<m;t++)
        {
            pre.clear(),suf.clear();
            Graph::n=n*4;
            for(int i=0;i<Graph::n;i++) 
                Graph::g[i].clear();
            for(int i=1;i<=n;i++)
            {
                ull L=geth(hs[i],1,t),R=geth(hs[i],t+1,m);
                if(!pre.count(L))
                    pre[L]=pre.size();
                if(!suf.count(R))
                    suf[R]=suf.size();
                Graph::g[pre[L]].push_back({suf[R]+n*2,i});
            }
            for(int i=1;i<=n;i++)
            {
                ull L=geth(ht[i],1,m-t),R=geth(ht[i],m-t+1,m);
                if(!suf.count(L))
                    suf[L]=suf.size();
                if(!pre.count(R))
                    pre[R]=pre.size();
                Graph::g[suf[L]+n*2].push_back({pre[R],i+n});
            }
            auto res=Graph::Euler();
            if(res.size()!=n*2)
                continue;
            vector<int> p,q;
            for(auto x:res)
                if(x<=n)
                    p.push_back(x);
                else
                    q.push_back(x-n);
            for(int i=0;i<n;i++)
                cout<<p[i]<<" \n"[i+1==n];
            for(int i=0;i<n;i++)
                cout<<q[i]<<" \n"[i+1==n];
            ok=1;
            break;
        }
        if(!ok)
            cout<<-1<<"\n";
    }
}

  

K. Randias Permutation Task

#include<bits/stdc++.h>
using namespace std;
int n , m;
vector<int> p[185] ;
vector<int> work(const vector<int> &A,const vector<int>& B)
{
    vector<int> C(A.size()) ;
    for(int i = 0;i < A.size();i++) C[i] = A[B[i]];
    return C;
}
int main()
{
    // freopen("in.txt","r",stdin) ;
    ios::sync_with_stdio(false) ; cin.tie(0) ;
    cin >> n >> m;
    for(int i = 1;i <= m;i++) {
        p[i].resize(n) ;
        for(auto &x : p[i]) {cin >> x; x--;}
    }
    set<vector<int> > st ;
    for(int i = 1;i <= m;i++) {
        vector<vector<int> > nv ;
        for(auto &V : st) nv.push_back(work(V , p[i])) ;
        st.insert(p[i]) ;
        for(auto &V : nv) st.insert(V) ;
    }
    cout << st.size() << '\n' ;
    return 0;
}

  

L. Alea Iacta Est

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
#define all(x) (x).begin(),(x).end()
const int N=1e6;
int mn[N+1],pr[N];
vector<pair<int,int>> getw(int n)
{
	vector<pair<int,int>> w;
	while (n>1)
	{
		int x=mn[n],y=1;
		n/=x;
		while (n%x==0) n/=x,++y;
		w.emplace_back(x,y);
	}
	return w;
}
void multiply(vector<int> &f,int p)//f*(1-x^p)/(1-x)
{
	int n=f.size(),i;
	for (i=n-p-1; i>=0; i--) f[i+p]-=f[i];
	for (i=1; i<n; i++) f[i]+=f[i-1];
}
void divide(vector<int> &f,int p)//f/(1-x^p)*(1-x)
{
	int n=f.size(),i;
	for (i=n-1; i; i--) f[i]-=f[i-1];
	for (i=0; i<n-p; i++) f[i+p]+=f[i];
}
vector<int> divide(int n,int p1,int p2)//(1-x^n)/((1-x)*Phi_{p1p2})
{
	assert(n%(p1*p2)==0);
	int m=p1*p2;
	int q=n/m,i;
	vector<int> f(n);
	for (i=0; i<q; i++) f[i*m]=1;
	multiply(f,p1);
	multiply(f,p2);
	return f;
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	int T; cin>>T;
	int cnt=0;
	{
		int i,j;
		mn[1]=1;
		for (i=2; i<=N; i++)
		{
			if (!mn[i])
			{
				mn[i]=i;
				pr[cnt++]=i;
			}
			for (j=0; i*pr[j]<=N; j++)
			{
				mn[i*pr[j]]=pr[j];
				if (i%pr[j]==0) break;
			}
		}
	}
	while (T--)
	{
		auto solve=[&]()->pair<vector<int>,vector<int>>
			{
				int n,m,i,j;
				cin>>n>>m;
				if (n>m) swap(n,m);
				auto wn=getw(n),wm=getw(m);
				for (int d=sqrtl((ll)n*m); d>n; d--) if ((ll)n*m%d==0)
				{
					int q=gcd(m,d);
					//n/p*q,m/q*p
					int p=(ll)n*q/d;
					assert(n%p==0);
					vector<int> a(n,1),b(m,1);
					a.resize(n+m);
					divide(a,p); divide(b,q);
					multiply(a,q); multiply(b,p);
					return {a,b};
				}
				if (n==1) return {vector(n,2),vector(m,1)};
				{
					if (wm.size()>1&&wm[0].first*wm[1].first<=n)
					{
						swap(n,m);
						swap(wn,wm);
					}
					if (wn.size()>1)
					{
						int p1=wn[0].first,p2=wn[1].first;
						auto a=divide(n,p1,p2);
						int p=p1*p2;
						vector<int> b(p);
						for (i=0; i<p2; i++) b[i*p1]=1;
						divide(b,p2);
						b.resize(m+p);
						multiply(b,m);
						return {a,b};
					}
				}
				assert(wn.size()==1);
				for (auto [pn,kn]:wn) for (auto [pm,km]:wm) if (pn==pm&&max(kn,km)>1)
				{
					bool flg=0;
					int p=pn;
					if (kn>km)
					{
						swap(kn,km);
						swap(n,m);
						flg=1;
					}
					vector<int> a(n*p),b(m);
					for (i=0; i*p<n; i++) for (j=0; j<p; j++) ++a[(i+j)*p];
					for (i=0; i*p*p<m; i++) b[i*p*p]=1;
					multiply(b,pn);
					multiply(b,pn);
					return {a,b};
				}
				if (wm.size()>=2)
				{
					int p1=wm[0].first;
					int p2=wm[1].first;
					assert(p1*p2==m);
					vector<int> a(n+m),b(m);
					for (i=0; i*p2<m; i++) a[i*p2]=1;
					divide(a,p1);
					multiply(a,n);
					if (*min_element(all(a))>=0)
					{
						for (i=0; i<p1; i++) for (j=0; j<p2; j++) ++b[i+j];
						return {a,b};
					}
				}
				for (i=n-1; i; i--) if ((ll)n*m%i==0)
				{
					ll m1=(ll)n*m/i;
					int n1=i;
					if (n1+m1>=n*2+m) break;
					int p=gcd(n,m1);
					//n/p*q,m/q*p
					int q=(ll)m*p/m1;
					assert(m%q==0);
					assert(p>q);
					vector<int> a(n,1),b(m,1);
					b.resize(m+p);
					divide(a,p); divide(b,q);
					multiply(a,q); multiply(b,p);
					return {a,b};
				}
				return {vector(n,2),vector(m,1)};
			};
		auto [a,b]=solve();
		//assert(!a.size()||*min_element(all(a))>=0);
		//assert(!b.size()||*min_element(all(b))>=0);
		int s1=accumulate(all(a),0),s2=accumulate(all(b),0);
	//	if (s1>s2) swap(s1,s2),swap(a,b);
		int n=a.size(),m=b.size(),i,j;
		cout<<s1;
		for (i=0; i<n; i++) while (a[i]--) cout<<' '<<i+1;
		cout<<'\n'<<s2;
		for (i=0; i<m; i++) while (b[i]--) cout<<' '<<i+1;
		cout<<'\n';
	}
}

  

M. Flipping Cards

#include<bits/stdc++.h>
using namespace std;
int main()
{
	ios_base::sync_with_stdio(false);
	int n;
	cin>>n;
	vector<int> a(n+5),b(n+5);
	for(int i=1;i<=n;i++)
	{
		cin>>a[i]>>b[i];
	}
	int hf=n/2+1;
	auto check=[&](int x)
	{
		int cur=0;
		for(int i=1;i<=n;i++)
			cur+=(a[i]>=x);
		int maxx=0,sum=0;
		for(int i=1;i<=n;i++)
		{
			int now=(b[i]>=x)-(a[i]>=x);
			sum+=now;
			sum=max(sum,0);
			maxx=max(maxx,sum);
		}
		return cur+maxx>=hf;
	};
	int l=1,r=1e9;
	while(l<r)
	{
		int mid=(l+r+1)/2;
		if(check(mid))l=mid;
		else r=mid-1;
	}
	cout<<l<<endl;
	return 0;
}

  

posted @ 2023-12-17 22:33  Claris  阅读(62)  评论(0编辑  收藏  举报