迟到的解题报告
JZOJ 4208 线段树什么的最讨厌了
题目
询问多段区间,是否存在一个 [ 0 ∼ n ] [0\sim n] [0∼n]的线段树为该区间
分析
那么区间 [ l ∼ r ] [l\sim r] [l∼r]可以扩展成 [ l ∼ r + t ] , [ l − t ∼ r ] , [ l − t − 1 ∼ r ] , [ l ∼ r + t − 1 ] ( t = r − l + 1 ) [l\sim r+t],[l-t\sim r],[l-t-1\sim r],[l\sim r+t-1](t=r-l+1) [l∼r+t],[l−t∼r],[l−t−1∼r],[l∼r+t−1](t=r−l+1)这样逆流而上,遇到 l = 0 l=0 l=0的时候 r r r即为答案
代码
#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
typedef unsigned ust;
ust lim,ans;
inline ust iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void dfs(ust l,ust r){
if (r>lim||r>ans||l>r) return;
if (!l) {ans=r; return;}
rr ust t=r-l+1;
if (r+t<=lim&&l>=(t<<1)) dfs(l,r+t);
if (l>=t) dfs(l-t,r);
if (r+t<lim&&l>=(t<<1)-1) dfs(l,r+t-1);
if (l==t+1||l>=t*3+2) dfs(l-t-1,r);
}
signed main(){
for (rr ust t=iut();t;--t){
rr ust l=iut(),r=iut(); lim=iut();
if (l==r||!l) printf("%u\n",r);
else if (r>lim) printf("-1\n");
else{
ans=2e9; dfs(l,r);
if (ans==2e9) printf("-1\n");
else printf("%u\n",ans);
}
}
return 0;
}
JZOJ 4209 【五校联考1day1】已经没有什么好害怕的了
题目
给定一个长度为n 只包含左括号和右括号的序列,问经过每一个位置的合法子串有多少个。如果A 和B 都是合法的串,那么(A) 和AB 都是合法的串。
分析
首先对于整个子串的增加个数可以用差分实现,然后用栈维护找到同级且相连的括号,用类似于双向链表的方式连接起来,然后对于每一个前驱和后继必须和括号有关,所以说用这样的方式求出答案
代码
#include <cstdio>
#include <cstring>
#include <stack>
#define rr register
using namespace std;
const int N=1000010,mod=1000000007;
int l[N+1],r[N+1],L[N+1],R[N+1];
signed main(){
rr int t; scanf("%d",&t);
while (t--){
rr char c=getchar(); rr int len=0;
rr stack<int>zh; rr long long ans=0,f=0;
while (c!='('&&c!=')') c=getchar();
while (c=='('||c==')'){
++len; if (c=='(') zh.push(len);
else if (zh.size()) l[r[zh.top()]=len+1]=zh.top(),zh.pop();
c=getchar();
}
for (rr int i=len+1;i;--i) R[l[i]]+=++R[i];
for (rr int i=1;i<=len;++i) L[r[i]]+=--L[i];
for (rr int i=1;i<=len;++i) ans+=(f+=L[i]+R[i])*i%mod;
memset(l,0,sizeof(l)); memset(r,0,sizeof(r));
memset(L,0,sizeof(L)); memset(R,0,sizeof(R));
printf("%lld\n",ans);
}
return 0;
}
JZOJ 4210 【五校联考1day1】我才不是萝莉控呢
题目
有一个长度为
n
n
n的正整数数组
A
A
A,满足
A
i
≥
A
i
+
1
A_i\geq A_{i+1}
Ai≥Ai+1,现在构造一个数组
B
B
B,令
B
i
=
∑
j
=
i
n
A
j
B_i=\sum_{j=i}^nA_j
Bi=∑j=inAj。
现在,有一个
n
×
n
n\times n
n×n的网格图,左下角坐标是
(
1
,
1
)
(1, 1)
(1,1),右上角坐标是
(
n
,
n
)
(n, n)
(n,n)。每一时刻,如果他现在在
(
x
,
y
)
(x, y)
(x,y),他可以选择走到
(
x
−
1
,
y
+
1
)
(x-1,y+1)
(x−1,y+1)或者
(
x
,
y
+
1
2
)
(x, \frac{y+1}{2})
(x,2y+1),如果选择后者,他要支付
B
x
B_x
Bx的代价。
现在他想从
(
n
,
1
)
(n,1)
(n,1)走到(1, 1),支付的代价最少是多少吗?注意在任何时候他都不能离开这个网格图。
分析
根据dalao的解释,如果倒过来推,只能向上或者掉下来,这长得很像哈夫曼树的合并,所以说合并果子原题