[考试反思]0523省选模拟104:原因

[考试反思]0523省选模拟104:原因

排名还是假的。因为$skyh$大神没有在联考里提交代码,所以显得好像又高了一名。

总之最近发挥异常的差。脑子也不怎么动了。改题效率也降低了。

开学前夕综合症?

难得遇到一套比较简单的题,其实$200pts$应该是轻轻松松的。

然后$T3$差几分钟没写完。$T2$没判无解直接爆零(期望$70$)

思考效率很低而且有明显的前松后紧(都多少次总是有一道题没打完了。。。$T3$就留了十几分钟可还行)

 

T1:签到题

大意:给定序列$A,w$,称$set(x)$为从$x$开始往后,最开始集合只有$\{ x \}$,每次找到比集合中最大元素更大的元素$A_y$就加入集合一直到序列末尾所得到的集合。

支持:给出$x$将所有$set(y)$中$x$是最小或次小元素的$w_y + = v_i$。给定$x,y$询问$( set(x) \cup set(y) )\cap [min(x,y) ,z]$中所有元素的$w$和。

其中$z$是$set(x)\cap set(y)\cap (min(x,y),n]$中的最小元素。如果不存在输出问号。$n,q \le 2 \times 10^5$

题目长的可怕。需要题意转化。

我们发现如果$x$后方第一个比$A_x$大的$A_y$,那么一定有$set(x) = set(y) \cup \{ x \}$。我们把这种包含关系建边自然就会形成一棵树。

再看一眼题目的操作,就是要支持:将一个点和它所有儿子权值加。询问一条路径的权值和(如果是祖先-后代链则还要跳一下父亲)

简单树剖线段树维护。所有儿子加比较麻烦于是改成当前点加二倍,额外开一个数组表示这个点被修改的总变化量$ex$。

那么一次询问除了线段树上的值,还要$-ex_x-ex_y+ex_{lca}+ex_{fa(lca)}$。分类讨论不算太麻烦。$O(nlog^2n)$

 1 #include<cstdio>
 2 #define S 400005
 3 int n,q,a[S],ec,fir[S],l[S],to[S];long long W[S],w[S<<2];
 4 void link(int a,int b){l[++ec]=fir[a];fir[a]=ec;to[ec]=b;}
 5 int sz[S],top[S],f[S],dfn[S],tim,dep[S],son[S],idfn[S];
 6 void dfs(int p,int fa){
 7     dep[p]=dep[fa]+1; sz[p]=1; f[p]=fa;
 8     for(int i=fir[p];i;i=l[i]){
 9         dfs(to[i],p);sz[p]+=sz[to[i]];
10         if(sz[son[p]]<sz[to[i]])son[p]=to[i];
11     }
12 }
13 void DFS(int p,int tp){
14     top[p]=tp; dfn[p]=++tim; idfn[tim]=p;
15     if(son[p])DFS(son[p],tp);
16     for(int i=fir[p];i;i=l[i])if(!dfn[to[i]])DFS(to[i],to[i]);
17 }
18 #define lc p<<1
19 #define rc lc|1
20 #define md (L+R>>1)
21 void build(int p=1,int L=1,int R=n+1){
22     if(L==R){w[p]=W[idfn[L]];W[idfn[L]]=0;return;}
23     build(lc,L,md);build(rc,md+1,R);w[p]=w[lc]+w[rc];
24 }
25 long long ask(int l,int r,int p=1,int L=1,int R=n+1){
26     if(l<=L&&R<=r)return w[p];
27     return (l<=md?ask(l,r,lc,L,md):0)+(r>md?ask(l,r,rc,md+1,R):0);
28 }
29 void add(int x,int v,int p=1,int L=1,int R=n+1){
30     w[p]+=v; if(L==R)return;
31     if(x<=md)add(x,v,lc,L,md);else add(x,v,rc,md+1,R);
32 }
33 void query(int x,int y){
34     long long ans=0;int rx=x,ry=y;
35     while(top[x]!=top[y]){
36         if(dep[top[x]]<dep[top[y]])x^=y^=x^=y;
37         ans+=ask(dfn[top[x]],dfn[x]);x=f[top[x]];
38     }if(dep[x]>dep[y])x^=y^=x^=y;
39     ans+=ask(dfn[x],dfn[y]);
40     if(x==rx||x==ry){if(x!=rx)rx^=ry^=rx^=ry;rx=f[rx];x=f[x];ans+=ask(dfn[x],dfn[x]);}
41     if(x==n+1||!x)puts("?");
42     else printf("%lld\n",ans-W[rx]-W[ry]+W[x]+W[f[x]]);
43 }
44 int main(){
45     scanf("%d%d",&n,&q);
46     for(int i=1;i<=n;++i)scanf("%d",&a[i]); a[n+1]=1e9;
47     for(int i=1;i<=n;++i)scanf("%lld",&W[i]);
48     static int sta[S],top; sta[++top]=n+1;
49     for(int i=n;i;--i){
50         while(a[sta[top]]<=a[i])top--;
51         link(sta[top],i);sta[++top]=i;
52     }
53     dfs(n+1,0);DFS(n+1,n+1);build();
54     for(int i=1,o,x,y;i<=q;++i){
55         scanf("%d%d%d",&o,&x,&y);
56         if(o-1)query(x,y);
57         else add(dfn[x],y*2),W[x]+=y;
58     }
59 }
View Code

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-02-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案