恩偶爱皮模拟尸体-31
作者:互联网
水博客太快乐了
考场
先大概看了下题。。。
感觉 \(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