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] ; ///長度,中心所在點,完整子樹標號,可以放置的節(jié)點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) ///長度,中心所在點,完整子樹標號,可以放置的節(jié)點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&°[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;
}

浙公網(wǎng)安備 33010602011771號