不闪躲 将深红唇色涂抹 让白瞳浸染烈火 感受心灵的赤裸 打开锁
test2
t4 能写那么多行真是头祝。t4 能写那么多行真是头祝。t4 能写那么多行真是头祝。t4 能写那么多行真是头祝。t4 能写那么多行真是头祝。t4 能写那么多行真是头祝。t4 能写那么多行真是头祝。
买礼物gift
枚举最大值贪心即可。
#include<bits/stdc++.h>
#define int long long
#define up(i,l,r) for(int i=l; i<=r; ++i)
#define dn(i,r,l) for(int i=r; i>=l; --i)
using namespace std;
const int N=200005;
int T, n, suf[N], Ans, sp[N];
struct node {
int a, b;
bool operator<(const node &rhs) const { return a<rhs.a; }
} p[N];
void mian() {
cin >> n, Ans=1e13;
up(i,1,n) cin >> p[i].a >> p[i].b;
sort(p+1,p+1+n);
suf[n+1]=-1e13;
dn(i,n,1) suf[i]=max(suf[i+1],p[i].b);
up(i,1,n) sp[i]=p[i].b;
sort(sp+1,sp+1+n);
map<int,int> tag;
up(i,1,n) {
Ans=min(Ans,abs(p[i].a-suf[i+1]));
int l=upper_bound(sp+1,sp+1+n,p[i].a)-sp-1;
int r=lower_bound(sp+1,sp+1+n,p[i].a)-sp;
l=sp[l], r=sp[r];
if(tag[l]&&l>suf[i+1]) Ans=min(Ans,abs(p[i].a-l));
if(tag[r]&&r>suf[i+1]) Ans=min(Ans,abs(p[i].a-r));
tag[p[i].b]=1;
// cout << i << " " << p[i].a << ' ' << suf[i+1] << ' ' << l << ' ' << r << '\n';
}
cout << Ans << '\n';
}
signed main() {
freopen("gift.in","r",stdin);
freopen("gift.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cin >> T;
while(T--) mian();
return 0;
}
追忆recall
要求约分后分母为 \(2^p5^q\),不妨先枚举 \(p,q\)。分数形如 \(\frac{yx}{(2^p5^q)x}\),对因数有要求,枚举一个另一个的方案数可以小容斥+整除分块计算。
#include<bits/stdc++.h>
#define int long long
#define up(i,l,r) for(int i=l; i<=r; ++i)
#define dn(i,r,l) for(int i=r; i>=l; --i)
#define pb push_back
using namespace std;
const int N=2000005;
int n, s[N], lr[N], tot, Ans;
int check(int p,int q) {
int mul=1;
while(p--) {
if(2*mul>n) return -1;
mul*=2;
}
while(q--) {
if(5*mul>n) return -1;
mul*=5;
}
return mul;
}
void mat(int op) {
int x=n/op, sum=0;
for(int l=1, r; l<=x; l=r+1) {
if(x/l) r=min(x,x/(x/l)); else r=x;
++tot, s[tot]=sum, lr[tot]=l;
sum+=(r-l+1)*(x/l);
}
// cout << "wq " << tot << '\n';
}
int sum(int op,int x) {
x=n/op/x;
if(x<1||!tot) return 0;
int l=1, r=tot, p;
while(l<=r) {
int mid=(l+r)>>1;
if(lr[mid]<=x) p=mid, l=mid+1;
else r=mid-1;
}
return s[p]+n/op/lr[p]*(x-lr[p]+1);
}
signed main() {
freopen("recall.in","r",stdin);
freopen("recall.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
mat(1);
up(p,0,100) up(q,0,100) {
int mul=check(p,q);
if(mul<0) continue;
Ans+=sum(1,mul);
} tot=0;
mat(2);
up(p,0,100) up(q,0,100) {
int mul=check(p,q);
if(mul<0) continue;
Ans-=sum(2,mul);
} tot=0;
mat(5);
up(p,0,100) up(q,0,100) {
int mul=check(p,q);
if(mul<0) continue;
Ans-=sum(5,mul);
} tot=0;
mat(10);
up(p,0,100) up(q,0,100) {
int mul=check(p,q);
if(mul<0) continue;
Ans+=sum(10,mul);
} tot=0;
cout << Ans;
return 0;
}
状元桥run
首先去重的 \(n'\) 级别是假的,因为显然至少要 \(\frac{(1+n)n}{2}\) 这么多的时间,所以位置种类只有不超过 \(O(L)\) 种。
然后可以观察到第一个拿的一定是 \(1/n\),理由是一个点一定在最后一次经过的时候拿,因为这个某一个时刻拿的球一定是一个前缀拼后缀,dp 求出最好情况即可。
#include<bits/stdc++.h>
#define int long long
#define up(i,l,r) for(int i=l; i<=r; ++i)
#define dn(i,r,l) for(int i=r; i>=l; --i)
#define pb push_back
using namespace std;
const int N=500005, M=1005;
int n, m, l, v[N], c[N], init[N], q, f[2][M][M][2], sl[N], sr[N];
inline void chk(int &a,int b) { a=min(a,b); }
signed main() {
// freopen("1.txt","r",stdin);
freopen("run.in","r",stdin);
freopen("run.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> l;
up(i,1,n) cin >> q, ++init[q];
up(i,0,l) if(init[i]) ++m, v[m]=i, c[m]=init[i];
up(i,1,m) sl[i]=sl[i-1]+c[i];
dn(i,m,1) sr[i]=sr[i+1]+c[i];
cin >> q;
if((1+m)*m/2>=5e5) {
while(q--) cout << "No\n";
return 0;
}
memset(f,0x3f,sizeof(f));
f[0][1][m+1][0]=f[1][0][m][1]=0;
up(i,1,m-1) {
up(l,0,i) {
int r=m+1-i+l;
// f[l][r] -> f[l+1][r]
chk(f[0][l+1][r][0],f[0][l][r][0]+abs(v[l]-v[l+1])*(sl[l]+sr[r]+1));
chk(f[0][l+1][r][0],f[0][l][r][1]+abs(v[r]-v[l+1])*(sl[l]+sr[r]+1));
chk(f[0][l][r-1][1],f[0][l][r][0]+abs(v[l]-v[r-1])*(sl[l]+sr[r]+1));
chk(f[0][l][r-1][1],f[0][l][r][1]+abs(v[r]-v[r-1])*(sl[l]+sr[r]+1));
// f[l][r] -> f[l][r-1]
chk(f[1][l+1][r][0],f[1][l][r][0]+abs(v[l]-v[l+1])*(sl[l]+sr[r]+1));
chk(f[1][l+1][r][0],f[1][l][r][1]+abs(v[r]-v[l+1])*(sl[l]+sr[r]+1));
chk(f[1][l][r-1][1],f[1][l][r][0]+abs(v[l]-v[r-1])*(sl[l]+sr[r]+1));
chk(f[1][l][r-1][1],f[1][l][r][1]+abs(v[r]-v[r-1])*(sl[l]+sr[r]+1));
}
}
while(q--) {
int s, t, lim, Ans=1e13;
cin >> s >> t >> lim;
int pre=upper_bound(v+1,v+1+m,t)-v-1, nxt=lower_bound(v+1,v+1+m,t)-v;
if(!pre) ++pre;
chk(Ans,abs(s-v[1])+f[0][pre][pre+1][0]+abs(t-v[pre])*(n+1));
chk(Ans,abs(s-v[1])+f[0][nxt-1][nxt][1]+abs(t-v[nxt])*(n+1));
chk(Ans,abs(s-v[m])+f[1][pre][pre+1][0]+abs(t-v[pre])*(n+1));
chk(Ans,abs(s-v[m])+f[1][nxt-1][nxt][1]+abs(t-v[nxt])*(n+1));
if(Ans+n<=lim) cout << "Yes\n"; else cout << "No\n";
}
return 0;
}
舞会party
先不管区间限制考虑问题。\(i\) 可以送礼物给 \(a_i>b_j\) 的 \(j\),要求 \(i\) 恰好出入度为 \(1\),显然是一个考虑是否存在完美匹配的问题,等价于求 \(|S|> |N(S)|\) 是否恒成立。
考虑一个集合 \(S\) 是否满足 \(|S|> |N(S)|\),又 \(a_i>b_i\) 不难发现满足仅有 \(S\) 中 \(a\) 的最大/次大值为 \(a_r/a_l\) 满足 \(a_l<b_r<a_l\) 且不存在 \(i(\neq S)\) 满足 \(b_i<a_i\)。
我们希望知道有没有 \(S\) 满足 \(|S|> |N(S)|\)(下称漂亮),不妨考虑 \(a_r\) 作为最大 \(a\) 是否能找出不合法 \(S\),所以考虑 \(i(\neq r)\) 是否放到 \(S\) 里面。
-
如果 \(a_i>a_r\),只能放到 \(S\) 外面,应该有 \(b_i>a_r\)。综合下来就是只用满足 \(b_i>a_r\) 就不会影响漂亮性。
-
如果 \(a_i<a_r\),如果放到 \(S\) 外面的话一定满足 \(b_i<a_r\) 一定会导致不漂亮,必须放到 \(S\) 里面,要求 \(a_i<b_r\)。综合下来就是只要满足 \(a_i<b_r\) 就不会影响漂亮性。
题目希望对于每一个 \(a_r\) 对应不出来漂亮的 \(S\),也就是存在一个一定影响漂亮性的 \(i\)。又因为题目是区间查询,对于每一个 \(a_r\) 我们只关心左右第一个 \(i\) 满足 \(b_i<a_r\) 且 \(a_i>b_r\)。这个可以 cdq 分治,但是也可以线段树,一维排序一次出现来偏序,令一位在线段树上维护区间最值,然后线段树二分找到位置即可。
对于每一个 \(r\) 希望 \(L_r/R_r\in [Q_l,Q_r]\),只需要查询是否存在 \(L_r<Q_l<r<Q_r<R_r\),二维偏序多来几次就行了。
#include<bits/stdc++.h>
#define int long long
#define up(i,l,r) for(int i=l; i<=r; ++i)
#define dn(i,r,l) for(int i=r; i>=l; --i)
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define pb push_back
using namespace std;
const int N=1000005;
int n, m, tot, ran, a[N], b[N], Ans[N], tr[N<<2], l[N], r[N], bit[N];
struct Query {
int i, id, v;
Query() {}
Query(int I,int Id,int V) { i=I, id=Id, v=V; }
bool operator<(const Query &rhs) const { return i<rhs.i; }
} arr[N];
struct node {
int id, l, r;
node() {}
node(int Id,int L,int R) { id=Id, l=L, r=R; }
bool operator<(const node &rhs) const {
if(l!=rhs.l) return l>rhs.l;
return id>rhs.id;
}
} p[N];
struct hypoxia {
int id, r, v;
hypoxia() {}
hypoxia(int Id,int R,int V) { id=Id, r=R, v=V; }
bool operator<(const hypoxia rhs) const { return r<rhs.r; }
} o[N];
void updata(int x,int v,int p=1,int s=1,int e=n) {
// cout << "upt " << x << ' ' << v << " : " << tr[1] << '\n';
if(s==e) { tr[p]=v; return; }
int mid=(s+e)>>1;
if(x<=mid) updata(x,v,ls(p),s,mid);
if(x>mid) updata(x,v,rs(p),mid+1,e);
tr[p]=max(tr[ls(p)],tr[rs(p)]);
}
int lower(int x,int v,int p=1,int s=1,int e=n) {
if(x<1||tr[p]<v) return 0;
int mid=(s+e)>>1, res=0;
if(1<=s&&e<=x) {
if(s==e) return s;
if(tr[rs(p)]>v) return lower(x,v,rs(p),mid+1,e);
return lower(x,v,ls(p),s,mid);
}
if(x>mid) res=lower(x,v,rs(p),mid+1,e);
if(!res) res=lower(x,v,ls(p),s,mid);
return res;
}
int upper(int x,int v,int p=1,int s=1,int e=n) {
// cout << "upper " << x << ' ' << v << " : " << s << ' ' << e << ' ' << p <<' ' << tr[p] << '\n';
// 查询 x 后面第一个 >v 的
if(x>n||tr[p]<v) return 0;
int mid=(s+e)>>1, res=0;
if(x<=s&&e<=n) {
if(s==e) return s;
if(tr[ls(p)]>v) return upper(x,v,ls(p),s,mid);
return upper(x,v,rs(p),mid+1,e);
}
if(x<=mid) res=upper(x,v,ls(p),s,mid);
if(!res) res=upper(x,v,rs(p),mid+1,e);
return res;
}
inline void add(int x,int v) {
if(x<1) return;
for( ; x<=n; x+=x&-x) bit[x]+=v;
}
inline int ask(int x=n) {
if(x<1) return 0;
int ret=0;
for( ; x; x-=x&-x) ret+=bit[x];
return ret;
}
inline void clear() {
ran=0;
up(i,1,n) bit[i]=0;
}
signed main() {
freopen("party.in","r",stdin);
freopen("party.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
up(i,1,n) cin >> a[i];
up(i,1,n) cin >> b[i];
up(i,1,n) {
arr[++tot]=Query(a[i],-i,b[i]);
arr[++tot]=Query(b[i],i,a[i]);
}
sort(arr+1,arr+1+tot);
up(u,1,tot) {
int i=arr[u].i, id=arr[u].id, v=arr[u].v;
// cout << id << ' ' << i << ' ' << v << '\n';
// cout << "sos " << tr[1] << '\n';
if(id>0) {
updata(id,v);
}
else {
id=-id;
l[id]=lower(id-1,v);
r[id]=upper(id+1,v);
// if(id==2) cout << "ranget " << v << ' ' << l[id] << ' ' << r[id] << '\n';
// exit(0);
}
}
up(i,1,n) if(!r[i]) r[i]=n+1;
// cout << "checklr\n"; up(i,1,n) cout << l[i] << ' ' << r[i] << '\n';
cin >> m;
up(i,1,m) {
p[++ran].id=-i;
cin >> p[ran].l >> p[ran].r;
Ans[i]=p[ran].l-p[ran].r-1;
}
up(i,1,m) {
o[++ran]=hypoxia(i,p[i].r,p[i].l);
o[++ran]=hypoxia(-i,p[i].l-1,p[i].l);
}
sort(o+1,o+1+ran);
int j=0;
up(i,1,ran) {
while(j<o[i].r) ++j, add(l[j],1);
int id=o[i].id;
if(id>0) Ans[id]+=ask()-ask(o[i].v-1);
else Ans[-id]-=ask()-ask(o[i].v-1);
}
// cout << "ans1 "; up(i,1,m) cout << Ans[i] << ' '; cout << '\n';
clear();
up(i,1,m) {
o[++ran]=hypoxia(i,p[i].r,p[i].r);
o[++ran]=hypoxia(-i,p[i].l-1,p[i].r);
} j=0;
sort(o+1,o+1+ran);
up(i,1,ran) {
while(j<o[i].r) ++j, add(r[j],1);
int id=o[i].id;
if(id>0) Ans[id]+=ask(o[i].v);
else Ans[-id]-=ask(o[i].v);
}
// cout << "ans2 "; up(i,1,m) cout << Ans[i] << ' '; cout << '\n';
clear(), ran=m;
up(i,1,n) {
p[++ran]=node(i,l[i],r[i]);
}
sort(p+1,p+1+ran);
up(u,1,ran) {
int id=p[u].id, R=p[u].r;
if(id>0) add(R,1);
else Ans[-id]-=ask(R);
}
clear();
up(i,1,m) {
// cout << "Ans = " << Ans[i] << '\n';
if(!Ans[i]) cout << "Yes\n";
else cout << "No\n";
}
return 0;
}