• bzoj3626: [LNOI2014]LCA奇技淫巧+树剖+线段树


    题目求[a,b]到c的lca深度之和   显然是一个满足区间减法的操作

    于是简化为

    [1,b]到c的lca深度之和

    (然并卵╮(╯▽╰)╭)然后就用奇技淫巧发现

    a和b的lca深度=先把根节点到a的路径都染色,然后查根节点到b的路径上染色点数

    只要把染色改为权值+1,就可以轻易解决区间的问题

    方法显然:离线,把询问排序,维护一棵兹磁区间加法和区间求和的线段树即可轻易解决

      1 #include <bits/stdc++.h>
      2 #define mid ((l+r)>>1)
      3 #define mod 201314
      4 using namespace std;
      5 int n,m,N,M,an,p,q,o;
      6 int size[50001],fa[50001],top[50001],pos[50001],son[50001],bro[50001],l[50001],r[50001],ans[100001];
      7 int sum[200001],flag[200001];
      8 struct quer
      9 {
     10     int r,x,bel;
     11 } que[100001];
     12 bool operator<(quer a,quer b){    return a.r<b.r;}
     13 void ins(int a,int b,int c)
     14 {
     15     que[++N].r=a;
     16     que[N].x=b;
     17     que[N].bel=c;
     18 }
     19 int build(int now)
     20 {
     21     size[now]=1;
     22     for(int i=son[now];i;i=bro[i])
     23         size[now]+=build(i);
     24     return size[now];
     25 }
     26 void pou(int now,int to)
     27 {
     28     int ma=0,id=0;top[now]=to;pos[now]=++M;
     29     for(int i=son[now];i;i=bro[i])
     30         if(size[i]>ma) ma=size[i],id=i;
     31     if(id) pou(id,to);
     32     for(int i=son[now];i;i=bro[i])
     33         if(i!=id) pou(i,i);
     34 }
     35 void push(int now,int l,int r)
     36 {
     37     if(flag[now] && l!=r)
     38     {
     39         sum[now*2]+=(mid-l+1)*flag[now];
     40         sum[now*2]%=mod;
     41         sum[now*2+1]+=(r-mid)*flag[now];
     42         sum[now*2]%=mod; 
     43         flag[now*2]+=flag[now];
     44         flag[now*2]%=mod;
     45         flag[now*2+1]+=flag[now];
     46         flag[now*2+1]%=mod;
     47         flag[now]=0;
     48     }
     49 }
     50 void add(int now,int l,int r,int x,int y)
     51 {
     52     if(l==x && r==y)
     53     {
     54         sum[now]+=r-l+1;flag[now]+=1;
     55         sum[now]%=mod;
     56         return;
     57     }
     58     push(now,l,r);
     59     if(x<=mid) add(now*2,l,mid,x,min(mid,y));
     60     if(y>mid) add(now*2+1,mid+1,r,max(x,mid+1),y);
     61     sum[now]=sum[now*2]+sum[now*2+1];
     62 }
     63 int query(int now,int l,int r,int x,int y)
     64 {
     65     if(l==x && r==y)
     66         return sum[now];
     67     push(now,l,r);
     68     int ans=0;
     69     if(x<=mid) ans+=query(now*2,l,mid,x,min(mid,y));
     70     if(y>mid) ans+=query(now*2+1,mid+1,r,max(x,mid+1),y);
     71     return ans;
     72 }
     73 void link(int now)
     74 {
     75     for(;now;now=fa[top[now]])
     76         add(1,1,M,pos[top[now]],pos[now]);
     77 }
     78 int qu(int now)
     79 {
     80     for(an=0;now;now=fa[top[now]])
     81         an=(an+query(1,1,M,pos[top[now]],pos[now]))%mod;
     82     return an;
     83 }
     84 int main()
     85 {
     86     scanf("%d%d",&n,&m);
     87     for(int i=2;i<=n;i++)
     88         scanf("%d",&fa[i]),++fa[i],
     89         bro[i]=son[fa[i]],son[fa[i]]=i;
     90     build(1);pou(1,1);
     91     for(int i=1;i<=m;i++)
     92     {
     93         scanf("%d%d%d",&p,&q,&o);
     94         l[i]=p;r[i]=++q;++o;
     95         if(p)ins(p,o,i);ins(q,o,i);
     96     }
     97     sort(que+1,que+N+1);
     98     int now=0;
     99     for(int i=1;i<=N;i++)
    100     {
    101         while(que[i].r>now) link(++now);
    102         int ret=qu(que[i].x);
    103         if(now==l[que[i].bel])
    104             ans[que[i].bel]-=ret;
    105         else
    106             ans[que[i].bel]+=ret;
    107     }
    108     for(int i=1;i<=m;i++)
    109         printf("%d
    ",(ans[i]+mod)%mod);
    110     return 0;
    111 }
  • 相关阅读:
    Shader实例:溶解效果(Dissolve)
    Shader实例:扭曲,漩涡
    Shader实例:边缘发光和描边
    Shader实例:2D流光
    基础知识:Q&A
    Shader实例:一台旧电视
    Unity Lightmap动态加载研究
    Excel转Json,Json转CSharp
    瓦特平台全部出售69.9元、为了学习、为了进步、为了明天!
    分享一个文件查找、替换制定的字符或数字之CS程序、附带源码
  • 原文地址:https://www.cnblogs.com/wanglichao/p/6425893.html
Copyright © 2020-2023  润新知