其他分享
首页 > 其他分享> > 恩偶爱皮模拟尸体-31

恩偶爱皮模拟尸体-31

作者:互联网

水博客太快乐了

RT

考场

先大概看了下题。。。
感觉 \(T2\) 比较可做,于是先看是水 \(T2\) ,口胡了一个结论,大概 \(50mins\) 写完了。。。
感觉大概是过了。。。。

然后去水 \(T1\) 又口胡了一个贪心,感觉显然是正确的。。。
考完发现显然是错误的。。。
又大概 \(1h\) 写完了。。。
感觉至少能拿到一半分。。。

然后去看 \(T3\) ,继续口胡,感觉树形结构是显然的(终于口胡对一个了。。。

分数

预估 : \(t1\ 40pts\ +\ t2\ 100pts\ +\ t3\ 45pts\ =\ 185pts\)
实际 : \(t1\ 10pts\ +\ t2\ 10pts\ +\ t3\ 45pts\ =\ 65pts\)
发现只有 \(t3\) 口胡的是对的。。。
其他口胡的都挂惨了。。。。
以后不要乱口胡了,至少给出一定的证明。。。
没有证明还不如交暴力分高。。。

题解

A. Game

code
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
inline int read(){
	int f=1, x=0; char ch=getchar();
	while(!isdigit(ch)) { if(ch=='-') f=-1; ch=getchar(); }
	while(isdigit(ch)) { x=x*10+ch-48; ch=getchar(); }
	return f*x;
}
int n;
int a[N], b[N], maxn, ans, M;
int l[N<<2], r[N<<2], s[N<<2];
void change(int x, int x1, int x2, int p){
	x+=M-1, l[x]+=x1, r[x]+=x2; x>>=1; int minn;
	for(; x; x>>=1){
		minn=min(l[x<<1], r[x<<1|1]);
		s[x]=s[x<<1]+s[x<<1|1]+minn;
		l[x]=l[x<<1]+l[x<<1|1]-minn;
		r[x]=r[x<<1]+r[x<<1|1]-minn;
	}
}
multiset<int> ul;
int main(void){
	n=read();
	for(int i=1; i<=n; ++i) maxn=max(maxn, a[i]=read());
	for(int i=1; i<=n; ++i) maxn=max(maxn, b[i]=read()), ul.insert(b[i]);
	for(M=1; M<maxn; M<<=1);
	for(int i=1; i<=n; ++i) change(a[i], 1, 0, 1), change(b[i], 0, 1, 1);
	ans=s[1];
	for(int i=1; i<=n; ++i){
		int l=a[i]+1, r=*ul.rbegin(), mid;
		change(a[i], -1, 0, 1);
		while(l<r){
			mid=(l+r+1)>>1;
			change(mid, 0, -1, 1);
			if(s[1]+1==ans) l=mid;
			else r=mid-1;
			change(mid, 0, 1, 1);
		}
		change(l, 0, -1, 1);
		if(l<=r&&1+s[1]==ans) { --ans, printf("%d ", l); ul.erase(ul.find(l)); continue; }
		change(l, 0, 1, 1);
		l=1, r=a[i];
		while(l<r){
			mid=(l+r+1)>>1;
			change(mid, 0, -1, 1);
			if(s[1]==ans) l=mid;
			else r=mid-1;
			change(mid, 0, 1, 1);
		}
		change(l, 0, -1, 1); ul.erase(ul.find(l));
		printf("%d ",l);
	}
	printf("\n");
	return 0;
}

\(ZKW\) 线段树又快又好写。。。

B. Time

code
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10, INF=0x3f3f3f3f;
inline int read(){
	int f=1, x=0; char ch=getchar();
	while(!isdigit(ch)) { if(ch=='-') f=-1; ch=getchar(); }
	while(isdigit(ch)) { x=x*10+ch-48; ch=getchar(); }
	return f*x;
}
int n, a[N], l, r, ans;
struct TRE{
	int l, r;
	int lz, min1, p, p1;
}t[N<<2];
void upd(int p){
	t[p].p=t[p<<1].min1 < t[p<<1|1].min1 ? t[p<<1].p : t[p<<1|1].p;
	t[p].p1=t[p<<1].min1 < t[p<<1|1].min1 ? t[p<<1].p1 : t[p<<1|1].p1;
	if(t[p<<1].min1==t[p<<1|1].min1) t[p].p1= min(t[p<<1].p1-l, r-t[p<<1].p1) < min(t[p<<1|1].p1-l, r-t[p<<1|1].p1) ? t[p<<1].p1 : t[p<<1|1].p1;
	if(t[p<<1].min1==t[p<<1|1].min1) t[p].p= min(t[p<<1].p1-l, r-t[p<<1].p1) < min(t[p<<1|1].p1-l, r-t[p<<1|1].p1) ? t[p<<1].p : t[p<<1|1].p;
	t[p].min1=min(t[p<<1].min1, t[p<<1|1].min1);
}
void pushdown(int p){
	if(!t[p].lz) return;
	int ls=p<<1, rs=p<<1|1;
	t[ls].p1+=t[p].lz, t[rs].p1+=t[p].lz;
	t[ls].lz+=t[p].lz, t[rs].lz+=t[p].lz;
	t[p].lz=0;
}
void built(int l, int r, int p){
	t[p].l=l, t[p].r=r;
	if(l==r) { t[p].min1=a[l]; t[p].p=l; t[p].p1=l; return; }
	int mid=(l+r)>>1;
	built(l, mid, p<<1); built(mid+1, r, p<<1|1);
	upd(p);
}
void erase(int x, int p){
	if(t[p].l==t[p].r) { t[p].p1=0; t[p].min1=INF; return; }
	pushdown(p); int mid=(t[p].l+t[p].r)>>1;
	if(x<=mid) erase(x, p<<1);
	else erase(x, p<<1|1); upd(p);
}
void deal(int l, int r, int x, int p){
	if(l<=t[p].l&&r>=t[p].r) { t[p].p1+=x; t[p].lz+=x; return; }
	pushdown(p); int mid=(t[p].l+t[p].r)>>1;
	if(l<=mid) deal(l, r, x, p<<1);
	if(r>mid) deal(l, r, x, p<<1|1);
}
int main(void){
	n=read(); l=1, r=n;
	for(int i=1; i<=n; ++i) a[i]=read();
	built(1, n, 1); int id, id1;
	for(int i=1; i<=n; ++i){
		id=t[1].p1; id1=t[1].p; ans+=min(id-l, r-id);
		if(l-id<r-id) deal(1, id1, 1, 1), ++l;
		else deal(id1, r, -1, 1), --r;
		erase(id1, 1);
	}
	printf("%d\n", ans);
	return 0;
}

C. Cover

code
#include<bits/stdc++.h>
using namespace std;
const int N=4e5+10;
#define ll long long
inline int read(){
	int f=1, x=0; char ch=getchar();
	while(!isdigit(ch)) { if(ch=='-') f=-1; ch=getchar(); }
	while(isdigit(ch)) { x=x*10+ch-48; ch=getchar(); }
	return f*x;
}
int n, m, fa[N];
ll ans;
struct S{
	int l, r, len, a;
	friend bool operator < (const S &x, const S &y) { return x.len > y.len; }
}s[N];
vector<int> l[N];
priority_queue<ll> q[N];
struct TRE{
	int l, r, id;
}t[N<<3];
void built(int l, int r, int p){
	t[p].l=l, t[p].r=r;
	if(l==r) return; int mid=(l+r)>>1;
	built(l, mid, p<<1), built(mid+1, r, p<<1|1);
}
int check(int l, int r, int p){
	if(l<=t[p].l&&r>=t[p].r) return t[p].id;
	int mid=(t[p].l+t[p].r)>>1;
	if(l<=mid&&r>mid) return max(t[p].id, max(check(l, r, p<<1), check(l, r, p<<1|1)));
	if(l<=mid) return max(t[p].id, check(l, r, p<<1));
	return max(t[p].id, check(l, r, p<<1|1));
}
void cover(int l, int r, int x, int p){
	if(l<=t[p].l&&r>=t[p].r) { t[p].id=x; return; }
	int mid=(t[p].l+t[p].r)>>1;
	if(l<=mid) cover(l, r, x, p<<1);
	if(r>mid) cover(l, r, x, p<<1|1);
}
int dep[N], son[N], top, mx[N];
ll stk[N];
void dfs(int u){
	for(int v : l[u]){
		dep[v]=dep[u]+1; dfs(v);
		if(mx[v]>mx[son[u]]) son[u]=v;
	}
	if(son[u]) swap(q[u], q[son[u]]);
	for(int v : l[u]){
		if(son[u]==v) continue; top=0;
		while(!q[v].empty()){
			stk[++top]=q[v].top()+q[u].top();
			q[u].pop(); q[v].pop();
		}
		while(top) q[u].push(stk[top--]);
	}
	q[u].push(s[u].a); mx[u]=max(dep[u], mx[son[u]]);
}
int main(void){
	n=read(), m=read();
	int x, y, z;
	for(int i=1; i<=m; ++i){
		x=read(), y=read(), z=read();
		s[i]=(S){x, y, y-x, z};
	}
	sort(s+1, s+1+m); built(1, n+1, 1);
	for(int i=1; i<=m; ++i){
		x=check(s[i].l, s[i].r, 1);
		cover(s[i].l, s[i].r, i, 1);
		l[x].push_back(i);
	}
	dfs(0);
	for(int i=1; i<=m; ++i){
		ans+=q[0].top(); q[0].pop();
		printf("%lld ", ans);
	}
	printf("\n");
	return 0;
}

标签:ch,return,int,31,mid,恩偶,while,getchar,爱皮
来源: https://www.cnblogs.com/CTcode/p/NOIP_31.html