题解 卡片
我 tm 没做出来这玩意……
考虑一个 \((A_i, B_i)\),先令 \(A_i\leqslant B_i\)
则能影响到它的 \(T\) 满足 \(T\geqslant A_i, B_i\)
考虑在一个 \(T\in[A_i, B_i-1]\) 的操作后卡牌肯定 B 面向上
那么找到最后一个满足上述条件的操作 \(j\),统计 \(j<k\and T_k\geqslant T_j\) 的个数即可
复杂度 \(O(n\log n)\)
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 600010
#define fir first
#define sec second
#define pb push_back
#define ll long long
//#define int long long
char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
int ans=0, f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans*f;
}
int n, k;
int a[N], b[N], t[N];
namespace force{
ll ans;
bool vis[N];
void solve() {
for (int i=1; i<=n; ++i) a[i]=read(), b[i]=read();
for (int i=1; i<=k; ++i) t[i]=read();
for (int i=1; i<=k; ++i)
for (int j=1; j<=n; ++j)
if (!vis[j]&&a[j]<=t[i]) vis[j]=1;
else if (vis[j]&&b[j]<=t[i]) vis[j]=0;
for (int i=1; i<=n; ++i) ans+=vis[i]?b[i]:a[i];
printf("%lld\n", ans);
}
}
// namespace task1{
// ll ans;
// const int blc=8192;
// pair<int, int> id[N];
// map<pair<int, int>, int> mp;
// pair<pair<int, int>, int> sta[N], tem[N];
// bitset<blc> A, B, one, apre[200010], bpre[200010];
// int uni[N], t2[N], aval[N], bval[N], ark[N], brk[N], aback[N], bback[N], usiz, top, atop, btop;
// void calc() {
// cout<<"calc"<<endl;
// cout<<"sta: "; for (int i=1; i<=top; ++i) cout<<"("<<sta[i].fir.fir<<','<<sta[i].fir.sec<<','<<sta[i].sec<<") "; cout<<endl;
// for (int i=1; i<=top; ++i) tem[i]={sta[i].fir, i};
// sort(tem+1, tem+top+1, [](pair<pair<int, int>, int> a, pair<pair<int, int>, int> b){return a.fir.fir<b.fir.fir;});
// for (int i=1; i<=top; ++i) aback[id[tem[i].sec].fir=i]=tem[i].sec;
// for (int i=1,now=0; i<=k; ++i) {
// while (now<top && t2[i]>=tem[now+1].fir.fir) ++now;
// ark[t2[i]]=now;
// }
// sort(tem+1, tem+top+1, [](pair<pair<int, int>, int> a, pair<pair<int, int>, int> b){return a.fir.sec<b.fir.sec;});
// for (int i=1; i<=top; ++i) bback[id[tem[i].sec].sec=i]=tem[i].sec;
// for (int i=1,now=0; i<=k; ++i) {
// while (now<top && t2[i]>=tem[now+1].fir.sec) ++now;
// brk[t2[i]]=now;
// }
// cout<<"id: "; for (int i=1; i<=top; ++i) cout<<"("<<id[i].fir<<','<<id[i].sec<<") "; cout<<endl;
// cout<<"t2: "; for (int i=1; i<=k; ++i) cout<<t2[i]<<' '; cout<<endl;
// cout<<"ark: "; for (int i=1; i<=10; ++i) cout<<ark[i]<<' '; cout<<endl;
// cout<<"brk: "; for (int i=1; i<=10; ++i) cout<<brk[i]<<' '; cout<<endl;
// for (int i=1; i<=top; ++i) apre[i]=apre[i-1], apre[i][id[aback[i]].sec]=1;
// for (int i=1; i<=top; ++i) bpre[i]=bpre[i-1], bpre[i][id[bback[i]].fir]=1;
// A.set(); B.reset();
// for (int i=1; i<=k; ++i) {
// A&=one<<ark[t[i]]; B&=one<<brk[t[i]];
// B|=apre[ark[t[i]]]; A|=bpre[brk[t[i]]];
// }
// for (int i=A._Find_first(); i<blc; i=A._Find_next(i)) ans+=1ll*uni[sta[aback[i]].fir.fir]*sta[aback[i]].sec;
// for (int i=B._Find_first(); i<blc; i=B._Find_next(i)) ans+=1ll*uni[sta[bback[i]].fir.sec]*sta[bback[i]].sec;
// }
// void solve() {
// one.set();
// // cout<<double(sizeof(apre)*2)/1000/1000<<endl; exit(0);
// for (int i=1; i<=n; ++i) uni[++usiz]=(a[i]=read()), uni[++usiz]=(b[i]=read());
// for (int i=1; i<=k; ++i) uni[++usiz]=(t[i]=read());
// sort(uni+1, uni+usiz+1);
// usiz=unique(uni+1, uni+usiz+1)-uni-1;
// for (int i=1; i<=n; ++i) ++mp[{a[i]=lower_bound(uni+1, uni+usiz+1, a[i])-uni, b[i]=lower_bound(uni+1, uni+usiz+1, b[i])-uni}];
// for (int i=1; i<=k; ++i) t2[i]=t[i]=lower_bound(uni+1, uni+usiz+1, t[i])-uni;
// sort(t2+1, t2+k+1);
// for (auto& it:mp) {
// sta[++top]=it;
// if (top==blc) calc();
// }
// if (top) calc();
// printf("%lld\n", ans);
// }
// }
namespace task1{
ll ans;
int dela[N], delb[N], atop, btop;
const int blc=10010;
pair<int, int> id[N];
map<pair<int, int>, int> mp;
bitset<blc> A, B, one, maska, maskb;
pair<pair<int, int>, int> sta[N], tem[N];
int uni[N], t2[N], ark[N], brk[N], aback[N], bback[N], usiz, top;
void calc() {
// cout<<"calc"<<endl;
// cout<<"sta: "; for (int i=1; i<=top; ++i) cout<<"("<<sta[i].fir.fir<<','<<sta[i].fir.sec<<','<<sta[i].sec<<") "; cout<<endl;
for (int i=1; i<=top; ++i) tem[i]={sta[i].fir, i};
sort(tem+1, tem+top+1, [](pair<pair<int, int>, int> a, pair<pair<int, int>, int> b){return a.fir.fir<b.fir.fir;});
for (int i=1; i<=top; ++i) aback[id[tem[i].sec].fir=i]=tem[i].sec;
for (int i=1,now=0; i<=k; ++i) {
while (now<top && t2[i]>=tem[now+1].fir.fir) ++now;
ark[t2[i]]=now;
}
sort(tem+1, tem+top+1, [](pair<pair<int, int>, int> a, pair<pair<int, int>, int> b){return a.fir.sec<b.fir.sec;});
for (int i=1; i<=top; ++i) bback[id[tem[i].sec].sec=i]=tem[i].sec;
for (int i=1,now=0; i<=k; ++i) {
while (now<top && t2[i]>=tem[now+1].fir.sec) ++now;
brk[t2[i]]=now;
}
// cout<<"id: "; for (int i=1; i<=top; ++i) cout<<"("<<id[i].fir<<','<<id[i].sec<<") "; cout<<endl;
// cout<<"t2: "; for (int i=1; i<=k; ++i) cout<<t2[i]<<' '; cout<<endl;
// cout<<"ark: "; for (int i=1; i<=10; ++i) cout<<ark[i]<<' '; cout<<endl;
// cout<<"brk: "; for (int i=1; i<=10; ++i) cout<<brk[i]<<' '; cout<<endl;
// for (int i=1; i<=top; ++i) apre[i]=apre[i-1], apre[i][id[aback[i]].sec]=1;
// for (int i=1; i<=top; ++i) bpre[i]=bpre[i-1], bpre[i][id[bback[i]].fir]=1;
A.reset(); B.reset();
for (int i=1; i<=top; ++i) A[i]=1;
// cout<<A<<endl;
// cout<<B<<endl;
for (int i=1; i<=k; ++i) {
// cout<<"i: "<<i<<endl;
for (int j=A._Find_first(); j<=ark[t[i]]; j=A._Find_next(j)) delb[++btop]=id[aback[j]].sec, A[j]=0;
for (int j=B._Find_first(); j<=brk[t[i]]; j=B._Find_next(j)) dela[++atop]=id[bback[j]].fir, B[j]=0;
// A&=one<<ark[t[i]]+1; B&=one<<brk[t[i]]+1;
// A|=maska; B|=maskb;
// for (int j=1; j<=atop; ++j) A[dela[j]]=0;
// for (int j=1; j<=btop; ++j) B[delb[j]]=0;
while (atop) A[dela[atop--]]=1;
while (btop) B[delb[btop--]]=1;
// cout<<A<<endl;
// cout<<B<<endl;
}
// cout<<A<<endl;
// cout<<B<<endl;
for (int i=A._Find_first(); i<blc; i=A._Find_next(i)) ans+=1ll*uni[sta[aback[i]].fir.fir]*sta[aback[i]].sec;
for (int i=B._Find_first(); i<blc; i=B._Find_next(i)) ans+=1ll*uni[sta[bback[i]].fir.sec]*sta[bback[i]].sec;
}
void solve() {
one.set();
// cout<<double(sizeof(apre)*2)/1000/1000<<endl; exit(0);
for (int i=1; i<=n; ++i) uni[++usiz]=(a[i]=read()), uni[++usiz]=(b[i]=read());
for (int i=1; i<=k; ++i) uni[++usiz]=(t[i]=read());
sort(uni+1, uni+usiz+1);
usiz=unique(uni+1, uni+usiz+1)-uni-1;
for (int i=1; i<=n; ++i) ++mp[{a[i]=lower_bound(uni+1, uni+usiz+1, a[i])-uni, b[i]=lower_bound(uni+1, uni+usiz+1, b[i])-uni}];
for (int i=1; i<=k; ++i) t2[i]=t[i]=lower_bound(uni+1, uni+usiz+1, t[i])-uni;
sort(t2+1, t2+k+1);
for (auto& it:mp) {
sta[++top]=it;
if (top==blc-5) calc(), top=0;
}
if (top) calc();
printf("%lld\n", ans);
}
}
namespace task{
ll ans;
vector<int> que[N];
#define ls(p) lson[p]
#define rs(p) rson[p]
#define pushup(p) maxn[p]=max(maxn[ls(p)], maxn[rs(p)])
int lson[N*50], rson[N*50], maxn[N*50], bit[N], uni[N], rot, usiz, tot;
inline void add(int i, int dat) {for (; i<=usiz; i+=i&-i) bit[i]+=dat;}
inline int query(int l, int r) {
int ans=0; l=max(--l, 0);
while (r>l) ans+=bit[r], r-=r&-r;
while (l>r) ans-=bit[l], l-=l&-l;
return ans;
}
void upd(int& p, int tl, int tr, int pos, int val) {
if (!p) p=++tot;
if (tl==tr) {maxn[p]=max(maxn[p], val); return ;}
int mid=(tl+tr)>>1;
if (pos<=mid) upd(ls(p), tl, mid, pos, val);
else upd(rs(p), mid+1, tr, pos, val);
pushup(p);
}
int query(int p, int tl, int tr, int ql, int qr) {
if (!p) return 0;
if (ql<=tl&&qr>=tr) return maxn[p];
int mid=(tl+tr)>>1, ans=0;
if (ql<=mid) ans=max(ans, query(ls(p), tl, mid, ql, qr));
if (qr>mid) ans=max(ans, query(rs(p), mid+1, tr, ql, qr));
return ans;
}
void solve() {
for (int i=1; i<=n; ++i) a[i]=read(), b[i]=read();
for (int i=1; i<=k; ++i) t[i]=read();
for (int i=1; i<=k; ++i) upd(rot, 1, 1e9, t[i], i);
for (int i=1,pos; i<=n; ++i) {
if (a[i]==b[i]) ans+=a[i];
else {
if ((pos=query(rot, 1, 1e9, min(a[i], b[i]), max(a[i], b[i])-1))&&a[i]<b[i]) swap(a[i], b[i]);
que[pos].pb(i);
// cout<<"i: "<<i<<' '<<pos<<endl;
}
}
for (int i=1; i<=k; ++i) uni[++usiz]=t[i];
sort(uni+1, uni+usiz+1);
usiz=unique(uni+1, uni+usiz+1)-uni-1;
for (int i=k; i; --i) {
int rk=lower_bound(uni+1, uni+usiz+1, t[i])-uni, cnt=query(rk, usiz);
for (auto it:que[i])
if (cnt&1) ans+=b[it];
else ans+=a[it];
add(rk, 1);
}
for (auto it:que[0]) {
if (b[it]>uni[usiz]) ans+=a[it];
else {
int rk=lower_bound(uni+1, uni+usiz, b[it])-uni;
if (query(rk, usiz)&1) ans+=b[it];
else ans+=a[it];
}
}
printf("%lld\n", ans);
}
}
signed main()
{
freopen("card.in", "r", stdin);
freopen("card.out", "w", stdout);
n=read(); k=read();
// if (n<=1000&&k<=1000) force::solve();
// else task1::solve();
task::solve();
return 0;
}