zoukankan      html  css  js  c++  java
  • codechef FIBTREE 码农题 线段树 树剖 标记永久化

    好烦啊,调了半天

    线段树部分标记比较多,手抖打错了一个

    剩下的都是取模的问题

    我自己瞎jb推的公式里保留了abs,但是在模意义下是gg的,所以必须把正负区分开

    调试的时候一定要注意构造各种形状的树,不要只做随机树

    随机树深度只有log,很难体现一些链上的性质

    我用随机树拍了一下午没出错,一掏出直链就秒秒钟出错

    最后找到了那个该死的abs

    还是逻辑不够严谨啊

      1 #include <bits/stdc++.h>
      2 #define DEBUG 0
      3 #define mid (l+r>>1)
      4 #define MOD 1000000009
      5 #define Que(rt,x,y) que(rt,1,n,x,y)
      6 #define Len (dep[x]-dep[top[x]]+1)
      7 using namespace std;
      8 struct node
      9 {
     10     int f,s,F,S,sum;
     11     node(long long a,long long b,long long c,long long d,long long e)
     12     {
     13         f=a%MOD;s=b%MOD;F=c%MOD;S=d%MOD;sum=e%MOD;
     14     }
     15     node()
     16     {
     17     }
     18 } tr[40000001];
     19 int ls[40000001],rs[40000001];
     20 int TIME,E,NODE,n,m,p,q,x,y;char ch;bool rev;
     21 int pos[200001],start[200001],en[200001];
     22 int dep[200001],top[200001],fa[200001],root[200001];
     23 int to[400001],nex[400001],fir[200001],size[200001];
     24 long long f[200001];
     25 int son(int x,int y)
     26 {
     27     while(dep[fa[top[y]]]>dep[x]) y=fa[top[y]];
     28     if(fa[top[y]]==x) return top[y];
     29     else return pos[start[x]+1];
     30 } 
     31 void add(int p,int q)
     32 {
     33     to[++E]=q;nex[E]=fir[p];fir[p]=E;
     34 }
     35 int build(int now,int fat)
     36 {
     37     fa[now]=fat;
     38     dep[now]=dep[fat]+1;
     39     size[now]=1;
     40     for(int i=fir[now];i;i=nex[i])
     41     if(to[i]!=fat) 
     42         size[now]+=build(to[i],now);
     43     return size[now];
     44 }
     45 void pou(int now,int Top)
     46 {
     47     top[now]=Top;start[now]=++TIME;pos[TIME]=now;
     48     int id=0;
     49     for(int i=fir[now];i;i=nex[i])
     50     if(to[i]!=fa[now])
     51         if(!id || size[to[i]]>size[id]) id=to[i];
     52     if(id) pou(id,Top);
     53     for(int i=fir[now];i;i=nex[i])
     54     if(to[i]!=fa[now] && to[i]!=id)
     55         pou(to[i],to[i]);
     56     en[now]=TIME;
     57 }
     58 int lca(int x,int y)
     59 {
     60     for(;top[x]!=top[y];x=fa[top[x]])
     61         if(fa[top[x]]<fa[top[y]]) swap(x,y);
     62     return dep[x]>dep[y]?y:x;
     63 }
     64 long long fib(int F,int S,int x)
     65 {
     66     if(x==1) return F;
     67     if(x==2) return S;
     68     return (f[x-2]*F+f[x-1]*S)%MOD;
     69 }
     70 long long getsum(int now,int x,int y)
     71 {
     72     if(y==1) return (tr[now].f+tr[now].F)%MOD;
     73     if(x==1 && y==2) return ((tr[now].f+tr[now].F)%MOD+(tr[now].s+tr[now].S)%MOD)%MOD;
     74     if(x==2 && y==2) return (tr[now].s+tr[now].S)%MOD;
     75     int F=(((y&1?1:-1)*f[y-2]*tr[now].F-(y&1?1:-1)*f[y-1]*tr[now].S)%MOD+MOD)%MOD,S=(((y&1?-1:1)*f[y-3]*tr[now].F+(y&1?1:-1)*f[y-2]*tr[now].S)%MOD+MOD)%MOD;
     76     return (fib(tr[now].f,tr[now].s,y+2)-fib(tr[now].f,tr[now].s,x+1)+MOD+fib(F,S,y-x+3)-S+MOD)%MOD;
     77 }
     78 int que(int now,int l,int r,int x,int y)
     79 {
     80     if(!now) return 0;
     81     if(l==x && r==y)
     82         return tr[now].sum;
     83     int ret=getsum(now,x-l+1,y-l+1);
     84     if(x<=mid) ret=(ret+que(ls[now],l,mid,x,min(y,mid)))%MOD;
     85     if(y>mid) ret=(ret+que(rs[now],mid+1,r,max(mid+1,x),y))%MOD;
     86     return ret; 
     87 }
     88 int add(int acc,int l,int r,int x,int y,int st,bool rev)
     89 {
     90     int now=++NODE;
     91     if(NODE>40000000) while(1); 
     92     tr[now]=tr[acc];
     93     if(l==x && r==y)
     94     {
     95         if(rev) tr[now]=node(tr[acc].f,tr[acc].s,tr[acc].F+f[st],tr[acc].S+f[st-1],tr[acc].sum+f[st+2]-f[st+l-r+1]+MOD);
     96         else tr[now]=node(tr[acc].f+f[st],tr[acc].s+f[st+1],tr[acc].F,tr[acc].S,tr[acc].sum+f[st+r-l+2]-f[st+1]+MOD);
     97         ls[now]=ls[acc];rs[now]=rs[acc];
     98         return now;
     99     }
    100     if(x<=mid && y<=mid)
    101         ls[now]=add(ls[acc],l,mid,x,y,st,rev),rs[now]=rs[acc];
    102     else
    103     if(y>mid && x>mid)
    104         ls[now]=ls[acc],rs[now]=add(rs[acc],mid+1,r,x,y,st,rev);
    105     else
    106     {
    107         ls[now]=add(ls[acc],l,mid,x,mid,st,rev);
    108         rs[now]=add(rs[acc],mid+1,r,mid+1,y,st+(rev?-1:1)*(mid-x+1),rev);
    109     }
    110     tr[now].sum=(tr[ls[now]].sum+tr[rs[now]].sum+getsum(now,1,r-l+1))%MOD;
    111     return now;
    112 }
    113 int main()
    114 {
    115     scanf("%d%d",&n,&m);
    116     for(int i=1;i<n;i++)
    117         scanf("%d%d",&p,&q),
    118         add(p,q),add(q,p);
    119     build(1,0);pou(1,1);
    120     f[1]=1;f[2]=1;
    121     for(int i=3;i<=n+10;i++)
    122     {
    123         f[i]=f[i-2]+f[i-1];
    124         if(f[i]>MOD) f[i]-=MOD;
    125     }
    126     root[0]=1;NODE=1;
    127     int lastans=0;
    128     for(int i=1;i<=m;i++)
    129     {
    130         root[i]=root[i-1];
    131         char S[10];
    132         scanf("%s",&S);
    133         if(S[0]=='A')
    134         {
    135             scanf("%d%d",&x,&y);
    136             if(!DEBUG)
    137             x^=lastans;
    138             if(x>n) while(1); 
    139             bool rev=0;int len=1,leng=dep[x]+dep[y]-2*dep[lca(x,y)]+1;
    140             for(;top[x]!=top[y];x=fa[top[x]])
    141             {
    142                 if(dep[top[x]]<dep[top[y]]) swap(x,y),rev^=1;
    143                 if(rev) leng-=Len;else len+=Len;
    144                 root[i]=add(root[i],1,n,start[top[x]],start[x],rev?leng+1:len-1,!rev);
    145             }
    146             if(dep[x]>dep[y]) swap(x,y),rev^=1;
    147             root[i]=add(root[i],1,n,start[x],start[y],rev?leng:len,rev);
    148         } 
    149         if(S[0]=='R')
    150         {
    151             scanf("%d",&x);
    152             if(!DEBUG)
    153             x^=lastans;
    154             if(x>=i) while(1);
    155             root[i]=root[x];
    156         }
    157         if(S[0]=='Q')
    158         {
    159             scanf("%d%d",&x,&y);
    160             if(!DEBUG)
    161             x^=lastans;
    162             if(x>n) while(1);
    163             int t=lca(x,y);
    164             if(S[1]=='S')
    165             if(x!=y) 
    166             if(t==y)
    167             {
    168                 int tem=son(y,x);
    169                 lastans=(Que(root[i],1,n)-Que(root[i],start[tem],en[tem])+MOD)%MOD;
    170             }
    171             else
    172                 lastans=Que(root[i],start[y],en[y]);
    173             else
    174                 lastans=Que(root[i],1,n);
    175             else
    176             {
    177                 lastans=0;
    178                 for(;top[x]!=top[y];x=fa[top[x]])
    179                 {
    180                     if(dep[top[x]]<dep[top[y]]) swap(x,y);
    181                     lastans+=Que(root[i],start[top[x]],start[x]);
    182                     lastans%=MOD;
    183                 }
    184                 if(dep[x]>dep[y]) swap(x,y);
    185                 lastans+=Que(root[i],start[x],start[y]);
    186                 lastans%=MOD;
    187             }
    188             printf("%d
    ",lastans);
    189         }
    190     }
    191     return 0;
    192 } 
  • 相关阅读:
    yun2win-iOS端IM SDK使用方法
    题解
    普通乘法,加法等时间复杂度计算
    noip2014 解方程(本博文转载于http://blog.csdn.net/popoqqq/article/details/40984859,略有删减)
    检查
    关于对拍 (来自老胡)
    2014 NOIP 赛前自我整理提醒。
    USACO 2014 JAN 滑雪录像
    Vue 双向绑定原理
    Vue 路由
  • 原文地址:https://www.cnblogs.com/wanglichao/p/7253432.html
Copyright © 2011-2022 走看看