zoukankan      html  css  js  c++  java
  • 2019.7.26 T1 树剖+双标记

    题目链接

    之前很久的一道题,还是写一写,这道题一眼就是树剖不用说了吧,但是它要同时支持区间赋值和加法操作,所以我们肯定需要两个标记,但是当赋值和加法标记同时下方的时候,就需要我们的细节处理,首先赋值的初始值应该赋为-1,而且下方的时候要先释放优先级高的赋值标记。区间赋值的时候,必须清空之前的加标记!当时考试的时候就是因为这样爆零了,惨痛的教训。

    代码如下:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int maxn=1e6+7;
      4 const int N=1e7+7;
      5 struct seg{
      6     int l,r,lazy1,lazy2;
      7     long long sum;
      8 }tree[maxn*10];
      9 struct node{
     10     int nxt,to;
     11 }edge[maxn*2];
     12 int n,m;
     13 int a[maxn];
     14 int dep[maxn],fa[maxn],size[maxn],id[maxn],son[maxn],rev[maxn],top[maxn];
     15 bool not_zhishu[N];
     16 int prime[maxn];
     17 int Time,cnt;
     18 int head[maxn];
     19 int opt,x,y,k;
     20 int st,ed;
     21 int jmr;
     22 bool flag;
     23 inline void Euler(){
     24     for( register int i=2;i<=10000000;i++){
     25         if(!not_zhishu[i]) prime[++prime[0]] = i;
     26         for(register int j=1;j<=prime[0]&&i*prime[j]<=10000000;j++){
     27             not_zhishu[i*prime[j]]=true;
     28             if(i%prime[j]==0) break;
     29         }
     30     }
     31 }
     32 inline void add(int u,int v){
     33     edge[++cnt].nxt=head[u];
     34     edge[cnt].to=v;
     35     head[u]=cnt;
     36 }
     37 inline void dfs1(int x,int f){
     38     dep[x]=dep[f]+1;
     39     fa[x]=f;
     40     size[x]=1;
     41     int maxson=-1;
     42     for(int i=head[x];i;i=edge[i].nxt){
     43         int v=edge[i].to;
     44         if(v==f) continue;
     45         dfs1(v,x);
     46         size[x]+=size[v];
     47         if(size[v]>maxson||son[x]==-1){
     48             maxson=size[v];
     49             son[x]=v;
     50         }
     51     }
     52 }
     53 inline void dfs2(int x,int topf){
     54     top[x]=topf;
     55     id[x]=++Time;
     56     rev[id[x]]=x;
     57     if(son[x]==-1) return;
     58     dfs2(son[x],topf);
     59     for(int i=head[x];i;i=edge[i].nxt){
     60         int v=edge[i].to;
     61         if(v==son[x]||v==fa[x]) continue;
     62         dfs2(v,v);
     63     }
     64 }
     65 inline void pushup(int x){
     66     tree[x].sum=tree[x*2].sum+tree[x*2+1].sum;
     67 }
     68 inline void pushdown(int x){
     69     if(tree[x].lazy2!=-1){
     70         tree[x*2].sum=tree[x].lazy2*(tree[x*2].r-tree[x*2].l+1);
     71         tree[x*2+1].sum=tree[x].lazy2*(tree[x*2+1].r-tree[x*2+1].l+1);
     72         tree[x*2].lazy2=tree[x].lazy2;
     73         tree[x*2+1].lazy2=tree[x].lazy2;
     74         tree[x].lazy2=-1;
     75         tree[x*2+1].lazy1=tree[x*2].lazy1=0;
     76     }
     77     if(tree[x].lazy1){
     78         tree[x*2].sum+=tree[x].lazy1*(tree[x*2].r-tree[x*2].l+1);
     79         tree[x*2+1].sum+=tree[x].lazy1*(tree[x*2+1].r-tree[x*2+1].l+1);
     80         tree[x*2].lazy1+=tree[x].lazy1;
     81         tree[x*2+1].lazy1+=tree[x].lazy1;
     82         tree[x].lazy1=0;
     83     }
     84 }
     85 inline void build(int now,int l,int r){
     86     tree[now].l=l;
     87     tree[now].r=r;
     88     tree[now].lazy1=0;
     89     tree[now].lazy2=-1;
     90     if(l==r){
     91         tree[now].sum=a[rev[l]];
     92         return;
     93     }
     94     int mid=(l+r)>>1;
     95     build(now*2,l,mid);
     96     build(now*2+1,mid+1,r);
     97     pushup(now);
     98 }
     99 inline void modify1(int now,int l,int r,int v){
    100     if(tree[now].l>=l&&tree[now].r<=r){
    101         tree[now].sum+=(tree[now].r-tree[now].l+1)*v;
    102         tree[now].lazy1+=v;
    103         return;
    104     }
    105     pushdown(now);
    106     int mid=(tree[now].l+tree[now].r)>>1;
    107     if(l<=mid) modify1(now*2,l,r,v);
    108     if(r>mid) modify1(now*2+1,l,r,v);
    109     pushup(now);
    110 }
    111 inline void modify2(int now,int l,int r,int v){
    112     if(tree[now].l>=l&&tree[now].r<=r){
    113         tree[now].lazy2=v;
    114         tree[now].sum=(tree[now].r-tree[now].l+1)*v;
    115         tree[now].lazy1=0;
    116         return;
    117     }
    118     pushdown(now);
    119     int mid=(tree[now].l+tree[now].r)>>1;
    120     if(l<=mid) modify2(now*2,l,r,v);
    121     if(r>mid) modify2(now*2+1,l,r,v);
    122     pushup(now);
    123 }
    124 inline int query(int now,int l,int r){
    125     if(tree[now].l>=l&&tree[now].r<=r) return tree[now].sum;
    126     int mid=(tree[now].l+tree[now].r)>>1;
    127     pushdown(now);
    128     int val=0;
    129     if(l<=mid) val+=query(now*2,l,r);
    130     if(r>mid) val+=query(now*2+1,l,r);
    131     return val;
    132 }
    133 inline void link1(int x,int y,int v){
    134     while(top[x]!=top[y]){
    135         if(dep[top[x]]<dep[top[y]]) swap(x,y);
    136         modify1(1,id[top[x]],id[x],v);
    137         x=fa[top[x]];
    138     }
    139     if(dep[x]<dep[y]) swap(x,y);
    140     modify1(1,id[y],id[x],v);
    141 }
    142 inline void link2(int x,int y,int v){
    143     while(top[x]!=top[y]){
    144         if(dep[top[x]]<dep[top[y]]) swap(x,y);
    145         modify2(1,id[top[x]],id[x],v);
    146         x=fa[top[x]];
    147     }
    148     if(dep[x]<dep[y]) swap(x,y);
    149     modify2(1,id[y],id[x],v);
    150 }
    151 inline void linkquery(int x,int y){
    152     int ans=0;
    153     while(top[x]!=top[y]){
    154         if(dep[top[x]]<dep[top[y]]) swap(x,y);
    155         ans+=query(1,id[top[x]],id[x]);
    156         x=fa[top[x]];
    157     }
    158     if(dep[x]<dep[y]) swap(x,y);
    159     ans+=query(1,id[y],id[x]);
    160     if(ans<=3){printf("TANOSHI
    ");return;}
    161     if(ans%2==0){printf("SUGOI
    ");return;}
    162     int tmp=ans-2;
    163     if(not_zhishu[tmp]){printf("TANOSHI
    ");return;}
    164     else{printf("SUGOI
    ");return;}
    165 }
    166 int main(){
    167 //    freopen("japari.in","r",stdin);
    168 //    freopen("japari.out","w",stdout); 
    169     memset(son,-1,sizeof(son));
    170     Euler();
    171     scanf("%d%d",&n,&m);
    172     for(register int i=1;i<=n;i++){
    173         scanf("%d",&a[i]);
    174     } 
    175     for(register int i=1;i<n;i++){
    176         scanf("%d%d",&st,&ed);
    177         add(st,ed);add(ed,st);
    178     }
    179     dfs1(1,0);
    180     dfs2(1,1);
    181     build(1,1,n);
    182     for(register int i=1;i<=m;i++){
    183         scanf("%d",&opt);
    184         if(opt==1){
    185             scanf("%d%d%d",&x,&y,&k);
    186             link1(x,y,k);
    187         }
    188         else if(opt==2){
    189             scanf("%d%d%d",&x,&y,&k);
    190             link2(x,y,k);
    191         }
    192         else{
    193             scanf("%d%d",&x,&y);
    194             linkquery(x,y);
    195         } 
    196     }
    197     return 0;
    198 }
    View Code
  • 相关阅读:
    RabbitMq、ActiveMq、ZeroMq 和 kafka 比较
    Mysql:The table‘xxxx’is full
    忘记了MariaDB root密码的解决办法
    在CentOS 7 MySQL / MariaDB
    SQL批量删除与批量插入
    org.springframework.web.servlet.PageNotFound No mapping found for HTTP request with URI [/AssetRepair/assetRepairController/test.do] in DispatcherServlet with name 'assetrepair'
    <spring:message> 标签
    Spring MVC之@RequestParam @RequestBody @RequestHeader 等详解
    实现JMS规范的ActiveMQ
    常见消息队列协议总结
  • 原文地址:https://www.cnblogs.com/LJB666/p/11371344.html
Copyright © 2011-2022 走看看