前言
music
《浮光》看指尖拨响蝴蝶 扇动一场离别我推开无声岁月 续梦一页你我只是打个照面 可曾有过誓约走进熟悉却 陌生的思念啊……啊……你的眼眸 装满了时间你的身后 拥故事成篇此生如梦 愿细数流年与你同写 沧海桑田浮光掠影 重山彩云间你的伏线 穿越千百年人生不过 恍惚三万天漫漫人间 留恋流连你说那月光 照过同样城墙永恒的刹那的 此刻沉默无话想问你这星空 是否不曾变是啊 是啊 我们望着它风吹过耳旁 古远的歌唱啊这是我也是你 不曾遗忘的啊是来路是去处 是你在回答去吧 去啊 总会相遇吧你的眼眸 装满了时间你的身后 拥故事成篇此生如梦 愿细数流年与你同写 沧海桑田浮光掠影 重山彩云间你的伏线 穿越千百年人生不过 恍惚三万天漫漫人间 留恋流连
先写点闲话。
明天(发的时候已经是今天了)就要放假了开心O(∩_∩)O~~,就放一天不开心 ̄へ ̄。
还要开家长会?不知道我们这种期中没考选科也毫无悬念的过来开家长会的意义何在……
明天还有模拟赛?到底打不打?真打的话打一半就得走。
晚上(21:10 左右)网没了?feifei 说出故障了,过了一会儿修复了。
宿舍的远古电话交换机太破了老是占线烦死了。
中午让我推歌,好耶放周深的,想要放《一期一会》,huge 说要放大家可能听过的跟着唱,不是都没听过《未闻花名》吗?改成《浮光》,还要我跟着唱,不是我耳朵有毛病不会跟着唱,深深唱得那么好听静静欣赏不好么,要么只听要么自己唱,好像机房听过这个的也不多(就算听过也唱不上去),一帮人默默地听没人唱。
好了该说比赛了,就是挂的快比得的分多了,T1 只筛到 \(m\) 被 hack 哩(全机房都被 hack 了),T2 部分分给了足足 \(80\),那我还想个屁正解直接写部分分,没开 long long 挂 \(30\)?!?T4 我会部分分!没打完……
T1 题面一开始还是错的,所以先打的 T2,T2 飞快拿到 \(80\) 后去写 T1,发现二分显然就开打,然后读假题了,我甚至在那儿怀疑大样例是错的都没有怀疑自己读假题了,瞪了 \(2\) 个多小时发现读假题了,发现加个埃筛就过了。
T2 出线段树分治板子,记得上次出珂朵莉维护颜色段板子也是部分分给了足足 \(80\)。
huge 坦白是往年学长加的 hack,还科普了为什么饮水机会漏。
T1 暴力操作
显然可以二分答案。
因为 \(\lfloor\dfrac{a}{bc}\rfloor=\lfloor\dfrac{\lfloor\frac{a}{b}\rfloor}{b}\rfloor\),对于一个 \((a_i,x)\) 所满足 \(\lfloor\dfrac{a_i}{x}\rfloor\le mid,x<y\) 一定满足 \(\lfloor\dfrac{a_i}{y}\rfloor\le mid\),所以先对于 \(c_i\) 做一次后缀 \(\min\),再跑一边埃筛(类似背包吧):\(\forall j\mid i,c_{i}=\min(c_i,c_j\times c_{\frac{i}{j}})\),之后再做一次后缀 \(\min\),使每次操作代价最小。
这里需要注意一个细节,不能只筛到 \(m\),如 \(n=7\),则 \(7\) 可以通过 \(3\times 3\) 替换掉,但此时他是 \(9\),所以 \(9\) 也要筛到,保险起见筛到 \(2m\)。
对于 check,先将 \(a\) 按升序排序,对于一个数是中位数的必要条件是 \(\sum\limits_{i=1}^n[a_i\le x]\ge \lfloor\dfrac{n}{2}\rfloor+1\),若满足就往左二分即可,满足该条件的最小的一个一定是中位数,对于 \(n\) 为奇数显然正确,对于 \(n\) 为偶数,考虑中位数等于 \(\dfrac{a_{\frac{n}{2}}+a_{\frac{n}{2}+1}}{2}\),现在显然有 \(a_{\frac{n}{2}}\le mid\),若能够使 \(a_{\frac{n}{2}+1}< mid\) 则此时中位数是 \(<mid\) 的,答案还能再小,直到最小的一个满足的。
具体如何找到一个 \(x\) 满足 \(\lfloor\dfrac{a_i}{x}\rfloor\le mid\),有 \(\dfrac{a_i}{x}<mid+1\),则 \(x>\dfrac{a_i}{mid+1}\),即 \(x\ge \lfloor\dfrac{a_i}{mid+1}\rfloor+1\),也可以双指针跑,D 一下部分人二分找 \(x\) 的双 \(\log\) 做法。
复杂度 \((n+m)\log m\)。
点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
#define sort stable_sort
using namespace std;
const int N=5e5+10;
template<typename Tp> inline void read(Tp&x)
{x=0;register bool z=true;register char c=getchar_unlocked();for(;!isdigit(c);c=getchar_unlocked()) if(c=='-') z=0;for(;isdigit(c);c=getchar_unlocked()) x=(x<<1)+(x<<3)+(c^48);x=(z?x:~x+1);
}
template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);}
template<typename Tp> inline void wt(Tp x){if(x>9)wt(x/10);putchar_unlocked((x%10)+'0');}
template<typename Tp> inline void write(Tp x){if(x<0)putchar_unlocked('-'),x=~x+1;wt(x);}
template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar_unlocked(' ');write(y...);}
int n,m,k,ans,a[N],b[N<<1];
inline bool check(int x)
{int pos=upper_bound(a+1,a+1+n,x)-a-1,res=0;if(pos>(n>>1)) return 1;for(int i=pos+1;i<=(n>>1)+1;i++) (res+=b[a[i]/(x+1)+1])>k&&(i=n);return res<=k;
}
signed main()
{freopen("opt.in","r",stdin),freopen("opt.out","w",stdout);read(n,m,k);for(int i=1;i<=n;i++) read(a[i]); sort(a+1,a+1+n);for(int i=1;i<=m;i++) read(b[i]); fill(b+m+1,b+2*m+1,1e9+1);for(int i=m-1;i;i--) b[i]=min(b[i],b[i+1]);for(int i=1;i<=2*m;i++) for(int j=2*i;j<=2*m;j+=i) b[j]=min(b[j],b[i]+b[j/i]);for(int i=2*m-1;i;i--) b[i]=min(b[i],b[i+1]);for(int l=0,r=m,mid;l<=r;) check(mid=l+r>>1)?r=(ans=mid)-1:l=mid+1;write(ans);
}
T2 异或连通
- P5787 二分图 /【模板】线段树分治。
发现每个 \(w_i\) 能够存在对应的区间不超过 \(\log k\) 段,这个是能够用 01trie 求出来的。
之后就是线段树分治板子了,就是在线段树上跑 dfs 加回溯,用可撤销并查集维护。
点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
#define sort stable_sort
#define mid (l+r>>1)
#define ls (mid<<1)
#define rs (mid<<1|1)
using namespace std;
const int N=1e5+10;
template<typename Tp> inline void read(Tp&x)
{x=0;register bool z=true;register char c=getchar_unlocked();for(;!isdigit(c);c=getchar_unlocked()) if(c=='-') z=0;for(;isdigit(c);c=getchar_unlocked()) x=(x<<1)+(x<<3)+(c^48);x=(z?x:~x+1);
}
template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);}
template<typename Tp> inline void wt(Tp x){if(x>9)wt(x/10);putchar_unlocked((x%10)+'0');}
template<typename Tp> inline void write(Tp x){if(x<0)putchar_unlocked('-'),x=~x+1;wt(x);}
template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar_unlocked(' ');write(y...);}
int n,m,q,k,top,res,tot=1,u[N],v[N],w[N],a[N],b[N],f[N],fa[N],sz[N],sta[N],ans[N],l[N<<5],r[N<<5],son[N<<5][2];
vector<int>g[N],t[N<<1]; unordered_map<int,int>mp;
inline int find(int x) {while(x!=fa[x]) x=fa[x]; return x;}
inline void merge(int x,int y)
{sz[x]>sz[y]&&(x^=y^=x^=y),fa[sta[++top]=x]=y,res-=f[y],res-=f[x];res+=(f[y]+=1ll*sz[x]*sz[y]+f[x]),sz[y]+=sz[x];
}
inline void undo(int ltop,int lres)
{for(int x,y;top>ltop;top--,f[y]-=1ll*sz[x]*sz[y]+f[x])x=sta[top],y=fa[sta[top]],sz[y]-=sz[x],fa[x]=x; res=lres;
}
inline void add(int p,int l,int r,int vl,int vr,int x)
{if(vl==0) return ; if(vl<=l&&vr>=r) return t[p].push_back(x),void(0);if(vl<=mid) add(ls,l,mid,vl,vr,x); if(vr>mid) add(rs,mid+1,r,vl,vr,x);
}
inline void ask(int p,int l,int r)
{int ltop=top,x,y,lres=res;for(int i:t[p]) if((x=find(u[i]))!=(y=find(v[i]))) merge(x,y);if(l==r) {for(int i:g[l]) ans[i]=res; return undo(ltop,lres),void();}ask(ls,l,mid),ask(rs,mid+1,r),undo(ltop,lres);
}
inline void insert(int x,int id)
{for(int i=30,p=1,c;~i;i--,r[p=son[p][c]]=id)if(!son[p][c=(x>>i)&1]) l[son[p][c]=++tot]=id;
}
inline void ask(int id)
{for(int i=30,p=1,c,d,j;~i&&p;i--){j=son[p][c=(w[id]>>i)&1],d=(k>>i)&1;if(d) add(1,1,b[0],l[j],r[j],id),p=son[p][c^1]; else p=j;}
}
signed main()
{freopen("xor.in","r",stdin),freopen("xor.out","w",stdout);read(n,m,q,k); for(int i=1;i<=n;i++) fa[i]=i,sz[i]=1;for(int i=1;i<=m;i++) read(u[i],v[i],w[i]);for(int i=1;i<=q;i++) read(a[i]),b[i]=a[i];sort(b+1,b+1+q),b[0]=unique(b+1,b+1+q)-b-1;for(int i=1;i<=b[0];i++) insert(b[i],mp[b[i]]=i);for(int i=1;i<=q;i++) g[mp[a[i]]].push_back(i);for(int i=1;i<=m;i++) ask(i); ask(1,1,b[0]);for(int i=1;i<=q;i++) write(ans[i]),puts("");
}
T3 诡异键盘
没有太大改的欲望,留最后改吧。
T4 民主投票
还没有改,有空马上改。