题目描述

输入

第一行有三个整数N、M和R,分别表示树的节点数、指令和询问总数,以及X国的据点。

接下来N-1行,每行两个整数X和Y,表示Katharon国的一条道路。

接下来M行,每行描述一个指令或询问,格式见题目描述。

输出

对于每个询问操作,输出所求的值。

样例输入

5 8 1
1 2
2 3
3 4
4 5
Sum 2 4
Increase 3 5 3
Minor 1 4
Sum 4 5
Invert 1 3
Major 1 2
Increase 1 5 2
Sum 1 5

样例输出

0
0
6
3
19

提示

1<=N,M<=50000.且对于运送操作1<=W<=1000

链修改、查询链上点权和、查询链上最大最小点权,这些操作直接用树链剖分+线段树就能解决。

重点是链翻转,这显然不能用线段树这种静态数据结构,所以将线段树维护$dfs$序换成平衡树动态维护$dfs$序。

对于链翻转操作,我们将每一段重链在$dfs$序上的区间都从$treap$中断裂出来,然后将这些重链断裂出来的$treap$再合并到一起,将根节点打上翻转标记,然后再将这些重链合并成的$treap$断裂开分别插入回原来$dfs$序上的位置即可。

因为树链剖分是从下往上找重链,在$dfs$序上就是从后往前找区间,所以合并和分裂还原时都要倒着操作(也就是从$dfs$序上靠前的区间开始操作),这样才能保证每次找$dfs$序上对应位置是正确的。

注意在链修改打标记时要立即下传一层,否则查询时可能会有查询点仍有标记未下传的情况。

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<bitset>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll z;
ll ans;
int x,y;
int n,m;
int cnt;
int tot;
int res;
int rot;
int miku;
int root;
int a,b,c,e;
char ch[20];
int s[50010];
int t[50010];
int L[50010];
int R[50010];
int r[50010];
int f[50010];
int d[50010];
ll mn[50010];
ll mx[50010];
ll sum[50010];
ll num[50010];
int ls[50010];
int rs[50010];
int son[50010];
int top[50010];
int siz[50010];
int rev[50010];
int val[50010];
int to[100010];
int size[50010];
int head[50010];
int next[100010];
ll INF=1ll<<60;
void add(int x,int y)
{
tot++;
next[tot]=head[x];
head[x]=tot;
to[tot]=y;
}
void dfs(int x)
{
d[x]=d[f[x]]+1;
siz[x]=1;
for(int i=head[x];i;i=next[i])
{
if(to[i]!=f[x])
{
f[to[i]]=x;
dfs(to[i]);
siz[x]+=siz[to[i]];
if(siz[to[i]]>siz[son[x]])
{
son[x]=to[i];
}
}
}
}
void dfs2(int x,int tp)
{
top[x]=tp;
s[x]=++res;
if(son[x])
{
dfs2(son[x],tp);
}
for(int i=head[x];i;i=next[i])
{
if(to[i]!=f[x]&&to[i]!=son[x])
{
dfs2(to[i],to[i]);
}
}
}
int build()
{
int rt=++cnt;
size[rt]=1;
mn[rt]=INF;
r[rt]=rand();
return rt;
}
void pushup(int rt)
{
size[rt]=size[ls[rt]]+size[rs[rt]]+1;
mn[rt]=val[rt];
mx[rt]=val[rt];
sum[rt]=val[rt];
if(ls[rt])
{
mx[rt]=max(mx[rt],mx[ls[rt]]);
mn[rt]=min(mn[rt],mn[ls[rt]]);
sum[rt]+=sum[ls[rt]];
}
if(rs[rt])
{
mx[rt]=max(mx[rt],mx[rs[rt]]);
mn[rt]=min(mn[rt],mn[rs[rt]]);
sum[rt]+=sum[rs[rt]];
}
}
void pushdown(int rt)
{
if(num[rt])
{
num[ls[rt]]+=num[rt];
num[rs[rt]]+=num[rt];
sum[ls[rt]]+=size[ls[rt]]*num[rt];
sum[rs[rt]]+=size[rs[rt]]*num[rt];
mn[ls[rt]]+=num[rt];
mn[rs[rt]]+=num[rt];
mx[ls[rt]]+=num[rt];
mx[rs[rt]]+=num[rt];
val[ls[rt]]+=num[rt];
val[rs[rt]]+=num[rt];
num[rt]=0;
}
if(rev[rt])
{
rev[ls[rt]]^=1;
rev[rs[rt]]^=1;
rev[rt]^=1;
swap(ls[rt],rs[rt]);
}
}
int merge(int x,int y)
{
pushdown(x);
pushdown(y);
if(!x||!y)
{
return x+y;
}
if(r[x]<r[y])
{
rs[x]=merge(rs[x],y);
pushup(x);
return x;
}
else
{
ls[y]=merge(x,ls[y]);
pushup(y);
return y;
}
}
void split(int rt,int &x,int &y,int k)
{
if(!rt)
{
x=y=0;
return ;
}
pushdown(rt);
if(size[ls[rt]]>=k)
{
y=rt;
split(ls[rt],x,ls[y],k);
pushup(rt);
}
else
{
x=rt;
split(rs[rt],rs[x],y,k-size[ls[rt]]-1);
pushup(rt);
}
}
void change(int x,int y,ll z)
{
while(top[x]!=top[y])
{
if(d[top[x]]<d[top[y]])
{
swap(x,y);
}
split(root,a,b,s[x]);
split(a,a,c,s[top[x]]-1);
num[c]+=z;
sum[c]+=size[c]*z;
mn[c]+=z;
mx[c]+=z;
val[c]+=z;
root=merge(merge(a,c),b);
x=f[top[x]];
}
if(d[x]>d[y])
{
swap(x,y);
}
split(root,a,b,s[y]);
split(a,a,c,s[x]-1);
num[c]+=z;
sum[c]+=size[c]*z;
mn[c]+=z;
mx[c]+=z;
val[c]+=z;
root=merge(merge(a,c),b);
}
void rotate(int x,int y)
{
res=0;
while(top[x]!=top[y])
{
if(d[top[x]]<d[top[y]])
{
swap(x,y);
}
split(root,a,b,s[x]);
split(a,a,c,s[top[x]]-1);
t[++res]=c;
L[res]=s[top[x]];
R[res]=s[x];
root=merge(a,b);
x=f[top[x]];
}
if(d[x]>d[y])
{
swap(x,y);
}
split(root,a,b,s[y]);
split(a,a,c,s[x]-1);
t[++res]=c;
L[res]=s[x];
R[res]=s[y];
root=merge(a,b);
for(int i=res;i>=1;i--)
{
miku=merge(miku,t[i]);
}
rev[miku]^=1;
for(int i=res;i>=1;i--)
{
split(miku,a,b,R[i]-L[i]+1);
miku=b;
split(root,c,e,L[i]-1);
root=merge(merge(c,a),e);
}
}
ll query_max(int x,int y)
{
ans=0;
while(top[x]!=top[y])
{
if(d[top[x]]<d[top[y]])
{
swap(x,y);
}
split(root,a,b,s[x]);
split(a,a,c,s[top[x]]-1);
ans=max(ans,mx[c]);
root=merge(merge(a,c),b);
x=f[top[x]];
}
if(d[x]>d[y])
{
swap(x,y);
}
split(root,a,b,s[y]);
split(a,a,c,s[x]-1);
ans=max(ans,mx[c]);
root=merge(merge(a,c),b);
return ans;
}
ll query_min(int x,int y)
{
ans=INF;
while(top[x]!=top[y])
{
if(d[top[x]]<d[top[y]])
{
swap(x,y);
}
split(root,a,b,s[x]);
split(a,a,c,s[top[x]]-1);
ans=min(ans,mn[c]);
root=merge(merge(a,c),b);
x=f[top[x]];
}
if(d[x]>d[y])
{
swap(x,y);
}
split(root,a,b,s[y]);
split(a,a,c,s[x]-1);
ans=min(ans,mn[c]);
root=merge(merge(a,c),b);
return ans;
}
ll query_sum(int x,int y)
{
ans=0;
while(top[x]!=top[y])
{
if(d[top[x]]<d[top[y]])
{
swap(x,y);
}
split(root,a,b,s[x]);
split(a,a,c,s[top[x]]-1);
ans+=sum[c];
root=merge(merge(a,c),b);
x=f[top[x]];
}
if(d[x]>d[y])
{
swap(x,y);
}
split(root,a,b,s[y]);
split(a,a,c,s[x]-1);
ans+=sum[c];
root=merge(merge(a,c),b);
return ans;
}
int main()
{
scanf("%d%d%d",&n,&m,&rot);
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
dfs(rot);
dfs2(rot,rot);
for(int i=1;i<=n;i++)
{
root=merge(root,build());
}
while(m--)
{
scanf("%s",ch);
scanf("%d%d",&x,&y);
if(ch[2]=='c')
{
scanf("%lld",&z);
change(x,y,z);
}
else if(ch[2]=='m')
{
printf("%lld\n",query_sum(x,y));
}
else if(ch[2]=='j')
{
printf("%lld\n",query_max(x,y));
}
else if(ch[2]=='n')
{
printf("%lld\n",query_min(x,y));
}
else
{
rotate(x,y);
}
}
}

加强版:

现在考虑将翻转操作加强,去掉规定翻转路径为从上往下的直链的条件(即不给出树根)。

做法与之前的类似,我们将路径看成两条从上往下的直链(即分成$lca->x$与$lca->y$两部分),可以肯定一条链的$dfs$序一定在另一条链的$dfs$序之前,那么为了确保在取出第一条链时不影响第二条链的$dfs$序,我们先对整条链$dfs$序较大的一条链进行操作再取出另一条链。这里有一点需要注意的就是$lca$所在重链的分配:如果操作链不是直链,那么$lca$所在重链分配给dfs序较小的一条链;否则分配给$dfs$序较大的一条链。这样我们就得到了树上两个开头相连的序列,显然是无法直接将两个序列连到一起就翻转的。我们将一个序列先翻转再接在另一个序列的前面,然后将整个序列一起翻转,将翻转后的序列拆分成原来的两部分并将第一部分翻转回来,最后分别插入回原$treap$,同样为了保证第二个插入的链的$dfs$序是对的,要先插入$dfs$序较小的链。

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
int r[50010];
int ls[50010];
int rs[50010];
ll sum[50010];
int val[50010];
int num[50010];
int mx[50010];
int mn[50010];
int rev[50010];
int size[50010];
int sz[50010];
int son[50010];
int top[50010];
int dep[50010];
int f[50010];
int s[50010];
int dfn;
int l1[50010];
int len1[50010];
int l2[50010];
int len2[50010];
int s1,s2;
int n,m;
char ch[10];
int cnt;
int tot;
int head[50010];
int nex[100010];
int to[100010];
int q[100010];
int x,y,z;
int root;
void add_edge(int x,int y)
{
tot++;
nex[tot]=head[x];
head[x]=tot;
to[tot]=y;
}
void dfs(int x)
{
size[x]=1;
for(int i=head[x];i;i=nex[i])
{
if(to[i]!=f[x])
{
f[to[i]]=x;
dep[to[i]]=dep[x]+1;
dfs(to[i]);
size[x]+=size[to[i]];
if(size[to[i]]>size[son[x]])
{
son[x]=to[i];
}
}
}
}
void dfs2(int x,int tp)
{
top[x]=tp;
s[x]=++dfn;
q[dfn]=x;
if(son[x])
{
dfs2(son[x],tp);
}
for(int i=head[x];i;i=nex[i])
{
if(to[i]!=f[x]&&to[i]!=son[x])
{
dfs2(to[i],to[i]);
}
}
}
int newnode(int x)
{
int rt=++cnt;
val[rt]=x;
r[rt]=rand();
size[rt]=1;
mx[rt]=mn[rt]=x;
sum[rt]=1ll*x;
return rt;
}
void pushup(int rt)
{
size[rt]=1;
mx[rt]=mn[rt]=val[rt];
sum[rt]=1ll*val[rt];
if(ls[rt])
{
sum[rt]+=sum[ls[rt]];
mx[rt]=max(mx[rt],mx[ls[rt]]);
mn[rt]=min(mn[rt],mn[ls[rt]]);
size[rt]+=size[ls[rt]];
}
if(rs[rt])
{
sum[rt]+=sum[rs[rt]];
mx[rt]=max(mx[rt],mx[rs[rt]]);
mn[rt]=min(mn[rt],mn[rs[rt]]);
size[rt]+=size[rs[rt]];
}
}
void flip(int rt)
{
rev[rt]^=1;
swap(ls[rt],rs[rt]);
}
void add(int rt,int value)
{
num[rt]+=value;
sum[rt]+=1ll*size[rt]*value;
mx[rt]+=value;
mn[rt]+=value;
val[rt]+=value;
}
void pushdown(int rt)
{
if(rev[rt])
{
rev[rt]=0;
flip(ls[rt]);
flip(rs[rt]);
}
if(num[rt])
{
add(ls[rt],num[rt]);
add(rs[rt],num[rt]);
num[rt]=0;
}
}
int merge(int x,int y)
{
if(!x||!y)
{
return x+y;
}
pushdown(x);
pushdown(y);
if(r[x]<r[y])
{
rs[x]=merge(rs[x],y);
pushup(x);
return x;
}
else
{
ls[y]=merge(x,ls[y]);
pushup(y);
return y;
}
}
void split(int rt,int &x,int &y,int k)
{
if(!rt)
{
x=y=0;
return ;
}
pushdown(rt);
if(size[ls[rt]]>=k)
{
y=rt;
split(ls[rt],x,ls[y],k);
pushup(rt);
}
else
{
x=rt;
split(rs[rt],rs[x],y,k-size[ls[rt]]-1);
pushup(rt);
}
}
void change(int x,int y,int value)
{
int a=0,b=0,c=0;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
{
swap(x,y);
}
split(root,a,c,s[x]);
split(a,a,b,s[top[x]]-1);
add(b,value);
root=merge(merge(a,b),c);
x=f[top[x]];
}
if(dep[x]>dep[y])
{
swap(x,y);
}
split(root,a,c,s[y]);
split(a,a,b,s[x]-1);
add(b,value);
root=merge(merge(a,b),c);
}
ll query_sum(int x,int y)
{
int a=0,b=0,c=0;
ll res=0ll;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
{
swap(x,y);
}
split(root,a,c,s[x]);
split(a,a,b,s[top[x]]-1);
res+=sum[b];
root=merge(merge(a,b),c);
x=f[top[x]];
}
if(dep[x]>dep[y])
{
swap(x,y);
}
split(root,a,c,s[y]);
split(a,a,b,s[x]-1);
res+=sum[b];
root=merge(merge(a,b),c);
return res;
}
int query_max(int x,int y)
{
int a=0,b=0,c=0;
int res=0;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
{
swap(x,y);
}
split(root,a,c,s[x]);
split(a,a,b,s[top[x]]-1);
res=max(res,mx[b]);
root=merge(merge(a,b),c);
x=f[top[x]];
}
if(dep[x]>dep[y])
{
swap(x,y);
}
split(root,a,c,s[y]);
split(a,a,b,s[x]-1);
res=max(res,mx[b]);
root=merge(merge(a,b),c);
return res;
}
int query_min(int x,int y)
{
int a=0,b=0,c=0;
int res=2147483647;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
{
swap(x,y);
}
split(root,a,c,s[x]);
split(a,a,b,s[top[x]]-1);
res=min(res,mn[b]);
root=merge(merge(a,b),c);
x=f[top[x]];
}
if(dep[x]>dep[y])
{
swap(x,y);
}
split(root,a,c,s[y]);
split(a,a,b,s[x]-1);
res=min(res,mn[b]);
root=merge(merge(a,b),c);
return res;
}
void turn_round(int x,int y)
{
int a=0,b=0,c=0,d=0;
s1=s2=0;
int fx=x,fy=y;
while(top[x]!=top[y])
{
if(dep[top[x]]>dep[top[y]])
{
l1[++s1]=s[top[x]];
len1[s1]=s[x];
x=f[top[x]];
}
else
{
l2[++s2]=s[top[y]];
len2[s2]=s[y];
y=f[top[y]];
}
}
if(dep[x]>dep[y])
{
swap(x,y);
}
if((s[fx]<s[fy]&&fx!=x)||(s[fx]>s[fy]&&fy==x))
{
l1[++s1]=s[x];
len1[s1]=s[y];
}
else if((s[fx]<s[fy]&&fx==x)||(s[fx]>s[fy]&&fy!=x))
{
l2[++s2]=s[x];
len2[s2]=s[y];
}
int rot1=0;
int rot2=0;
int leng=0;
if(s[fx]<s[fy])
{
for(int i=1;i<=s2;i++)
{
split(root,a,c,len2[i]);
split(a,a,b,l2[i]-1);
root=merge(a,c);
rot2=merge(b,rot2);
}
for(int i=1;i<=s1;i++)
{
split(root,a,c,len1[i]);
split(a,a,b,l1[i]-1);
root=merge(a,c);
rot1=merge(b,rot1);
leng+=len1[i]-l1[i]+1;
}
flip(rot1);
rot1=merge(rot1,rot2);
flip(rot1);
split(rot1,a,b,leng);
flip(a);
rot1=a,rot2=b;
for(int i=s1;i>=1;i--)
{
split(rot1,a,b,len1[i]-l1[i]+1);
rot1=b;
split(root,c,d,l1[i]-1);
root=merge(merge(c,a),d);
}
for(int i=s2;i>=1;i--)
{
split(rot2,a,b,len2[i]-l2[i]+1);
rot2=b;
split(root,c,d,l2[i]-1);
root=merge(merge(c,a),d);
}
}
else
{
for(int i=1;i<=s1;i++)
{
split(root,a,c,len1[i]);
split(a,a,b,l1[i]-1);
root=merge(a,c);
rot1=merge(b,rot1);
}
for(int i=1;i<=s2;i++)
{
split(root,a,c,len2[i]);
split(a,a,b,l2[i]-1);
root=merge(a,c);
rot2=merge(b,rot2);
leng+=len2[i]-l2[i]+1;
}
flip(rot2);
rot2=merge(rot2,rot1);
flip(rot2);
split(rot2,a,b,leng);
flip(a);
rot2=a,rot1=b;
for(int i=s2;i>=1;i--)
{
split(rot2,a,b,len2[i]-l2[i]+1);
rot2=b;
split(root,c,d,l2[i]-1);
root=merge(merge(c,a),d);
}
for(int i=s1;i>=1;i--)
{
split(rot1,a,b,len1[i]-l1[i]+1);
rot1=b;
split(root,c,d,l1[i]-1);
root=merge(merge(c,a),d);
}
}
}
int main()
{
srand(12378);
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
add_edge(x,y);
add_edge(y,x);
}
dfs(1);
dfs2(1,1);
for(int i=1;i<=n;i++)
{
root=merge(root,newnode(0));
}
while(m--)
{
scanf("%s%d%d",ch,&x,&y);
if(ch[2]=='c')
{
scanf("%d",&z);
change(x,y,z);
}
else if(ch[2]=='v')
{
turn_round(x,y);
}
else if(ch[2]=='m')
{
printf("%lld\n",query_sum(x,y));
}
else if(ch[2]=='j')
{
printf("%d\n",query_max(x,y));
}
else
{
printf("%d\n",query_min(x,y));
}
}
}

BZOJ3159决战——树链剖分+非旋转treap(平衡树动态维护dfs序)的更多相关文章

  1. BZOJ3729Gty的游戏——阶梯博弈+巴什博弈+非旋转treap(平衡树动态维护dfs序)

    题目描述 某一天gty在与他的妹子玩游戏.妹子提出一个游戏,给定一棵有根树,每个节点有一些石子,每次可以将不多于L的石子移动到父节点,询问将某个节点的子树中的石子移动到这个节点先手是否有必胜策略.gt ...

  2. BZOJ3786星系探索——非旋转treap(平衡树动态维护dfs序)

    题目描述 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球.主星球没有依赖星球. ...

  3. 平衡树及笛卡尔树讲解(旋转treap,非旋转treap,splay,替罪羊树及可持久化)

    在刷了许多道平衡树的题之后,对平衡树有了较为深入的理解,在这里和大家分享一下,希望对大家学习平衡树能有帮助. 平衡树有好多种,比如treap,splay,红黑树,STL中的set.在这里只介绍几种常用 ...

  4. HDU 3966 Aragorn's Story 动态树 树链剖分

    Aragorn's Story Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  5. 【NOI复习】树链剖分

    简介 树链剖分通常用来解决一类维护静态树上路径信息的问题, 例如:给定一棵点带权树, 接下来每次操作会修改某条路径上所有点的权值(修改为同一个值或是同加上一个值等) , 以及询问某条路径上所有点的权值 ...

  6. 【ZJOI2008】树的统计(树链剖分)

    题面 Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II ...

  7. 2018.10.12 bzoj4712: 洪水(树链剖分)

    传送门 树链剖分好题. 考虑分开维护重儿子和轻儿子的信息. 令f[i]f[i]f[i]表示iii为根子树的最优值,h[i]h[i]h[i]表示iii重儿子的最优值,g[i]g[i]g[i]表示iii所 ...

  8. Hdu 5052 Yaoge’s maximum profit(树链剖分)

    题目大意: 给出一棵树.每一个点有商店.每一个商店都有一个价格,Yaoge每次从x走到y都能够在一个倒卖商品,从中得取利益.当然,买一顶要在卖之前.可是没次走过一条路,这条路上的全部商品都会添加一个v ...

  9. 树链剖分 树剖求lca 学习笔记

    树链剖分 顾名思义,就是把一课时分成若干条链,使得它可以用数据结构(例如线段树)来维护 一些定义: 重儿子:子树最大的儿子 轻儿子:除了重儿子以外的儿子 重边:父节点与重儿子组成的边 轻边:除重边以外 ...

随机推荐

  1. ubuntu RPLIDAR A2的使用

    RPLIDAR是由RoboPeak Team,SlamTec公司开发的低成本2D LIDAR解决方案.它可以扫描6度半径内的360°环境. RPLIDAR的输出非常适合构建地图,做slam或构建3D模 ...

  2. Android学习之基础知识五—Android常用的七大控件

    一.TextView控件:在界面上显示一段文本信息 先看XML代码和执行效果:         代码分析: 1.android:id属性,给当前控件定义了一个唯一的标识符 2.android:layo ...

  3. C语言程序设计II—第九周教学

    第九周教学总结(22/4-28/4) 教学内容 本周的教学内容为: 9.1 输出平均分最高的学生信息 知识点:结构的概念.结构的定义形式.结构的嵌套定义.结构变量和结构成员变量的引用.重难点:结构变量 ...

  4. C语言程序设计II—第七周教学

    第七周教学总结(8/4-14/4) 教学内容 本周的教学内容为:8.3 冒泡排序,知识点:指针与数组.重点难点:指针.数组与地址的关系:数组名作为函数参数.要求学生能够使用数组名作为函数参数进行熟练编 ...

  5. Bootstrap Search Suggest 下拉框模糊查询

    源码地址:https://github.com/lzwme/bootstrap-suggest-plugin 有时间会完善!暂时有点忙!

  6. P1438 无聊的数列

    P1438 无聊的数列 链接 分析: 等差数列可加,首项相加,公差相加. 代码: #include<cstdio> #include<algorithm> #include&l ...

  7. testNG-失败用例重跑方法探究

    实现IRetryAnalyzer类,重写其中的retry方法public class TestNGRetry implements IRetryAnalyzer { private int retry ...

  8. ZJOI2008 生日聚会Party

    对于任意连续区间的限制,可以转化为以i结尾的所有区间的限制.这个转换在昨天的后缀自动机题也有用到,因此将其命名为区后变换.稍加分析后,我们记录以i结尾任意区间最大差即可进行DP转移.这个转换同时也创造 ...

  9. 牛客国庆集训派对Day6 B.Board

    链接 [https://www.nowcoder.com/acm/contest/206/B] 分析 只要在n*n范围内随便找一个斜对角的一个格子去计算就知道了 具体看代码体会吧 代码 #includ ...

  10. Java的首次学习和了解

    先来说说自己对于Java的了解.Java是一种面向对象的语言,而c++则是面向过程的.Java在网页的开发设计制作过程中必不可少,另外我们还可以用它来做手机的移动开发,还有一些基于服务器的架构设计.J ...