题解 卡片

传送门

我 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;
}
posted @ 2022-05-30 21:59  Administrator-09  阅读(2)  评论(0编辑  收藏  举报