zoukankan      html  css  js  c++  java
  • 装饰

    题目描述

    Kokoa拼完了圣诞树,但是Chino觉得圣诞树光秃秃的一点不好看,所以决定装饰一下圣诞树。一开始所有点的权值pi为0, Chino每一次会选择树上两个点s,t,对于s-t,设上面的点为v1-k,给pvi加上iXRi。同时,Chino也会查询两个点a,b之间的简单路径上的所有点(包括a,b)的权值和(mod 100711433)。Chino还要接客,所以请你帮帮她。

    输入

    第一行3个整数 n,R,q
    接下来n-1行 每行两个数a,b表示有一条边a,b
    接下来q行 每行第一个数y表示操作种类
    y=0 接下来3个整数 x,s,t 表示装饰操作
    y=1 接下来2个整数 s,t 表示查询操作

    输出

    对于每个查询操作,单独一行输出一个数表示答案

    样例输入

    5 2 4
    1 2
    2 3
    2 4
    1 5
    0 3 3 4
    0 3 2 5
    1 3 4
    1 2 5
    

    样例输出

    108
    126
    

    提示

    数据范围
    30% n<=1e3 q<=2e3
    另外20% R=1 X=1
    另外30% 所有的装饰操作在查询操作之前
    100% n<=1e5 q<=2e5 R,X<=1e9
     
    这题考场我绝对码不动。。
    首先树链剖分。
    那么我们要用线段树来维护区间加$iXR^i$
    那么我们发现$iXR^i$可以拆分成$(i-1)XR^i$和$XR,2XR^2…$
    那么我们就可以用线段树来维护这两个标记了。
      1 #pragma GCC optimize(2)
      2 #include <bits/stdc++.h>
      3 using namespace std;
      4 #define M 200010
      5 #define MOD 100711433
      6 #define LL long long
      7 inline int read() {
      8     char ch = getchar(); int x = 0, f = 1;
      9     while(ch < '0' || ch > '9') {
     10         if(ch == '-') f = -1;
     11         ch = getchar();
     12     }
     13     while('0' <= ch && ch <= '9') {
     14         x = x * 10 + ch - '0';
     15         ch = getchar();
     16     }
     17     return x * f;
     18 }
     19 struct Edge{
     20     int u, v, Next;
     21 } G[M * 2];
     22 int n, R, Q;
     23 int head[M], tot;
     24 int sz[M], id[M], Top[M], fa[M];
     25 int h[M], dfs_clock;
     26 int q1[M], q2[M];
     27 int q[M * 4];
     28 int lz1[M * 4], lz2[M * 4], lz3[M * 4], lz4[M * 4];
     29 inline void add(int u, int v) {
     30     G[++ tot] = (Edge){u, v, head[u]};
     31     head[u] = tot;
     32 }
     33 inline void dfs1(int x, int f) {
     34     fa[x] = f; sz[x] = 1;
     35     h[x] = h[f] + 1;
     36     for(int i = head[x]; i != -1; i = G[i].Next) {
     37         if(G[i].v == f) continue;
     38         dfs1(G[i].v, x);
     39         sz[x] += sz[G[i].v];
     40     }
     41 }
     42 inline void dfs2(int x, int f) {
     43     int mx = 0; id[x] = ++ dfs_clock;
     44     for(int i = head[x]; i != -1; i = G[i].Next) {
     45         if(G[i].v == f) continue;
     46         if(sz[G[i].v] > sz[mx]) mx = G[i].v;
     47     }
     48     if(mx) {
     49         Top[mx] = Top[x];
     50         dfs2(mx, x);
     51     }
     52     for(int i = head[x]; i != -1; i = G[i].Next) {
     53         if(G[i].v == f || G[i].v == mx) continue;
     54         Top[G[i].v] = G[i].v;
     55         dfs2(G[i].v, x);
     56     }
     57 }
     58 inline int lca(int x, int y) {
     59     while(Top[x] != Top[y]) {
     60         if(h[Top[x]] < h[Top[y]]) swap(x, y);
     61         x = fa[Top[x]];
     62     }
     63     return (h[x] < h[y] ? x : y);
     64 }
     65 int mi[M];
     66 inline void init() {
     67     mi[0] = 1;
     68     for(int i = 1; i <= n; ++ i) {
     69         mi[i] = 1ll * mi[i - 1] * R % MOD;
     70     }
     71     for(int i = 1; i <= n; ++ i) {
     72         q1[i] = q1[i - 1] + mi[i - 1];
     73         if(q1[i] >= MOD) q1[i] -= MOD;
     74     }
     75     for(int i = 1; i <= n; ++ i) {
     76         q2[i] = q2[i - 1] + 1ll * i * mi[i - 1] % MOD;
     77         if(q2[i] >= MOD) q2[i] -= MOD;
     78     }
     79 }
     80 inline void pd(int l, int mid, int r, int o) {
     81     if(lz1[o]) {
     82         q[2 * o] += 1ll * lz1[o] * q1[mid - l + 1] % MOD;
     83         if(q[2 * o] >= MOD) q[2 * o] -= MOD;
     84         q[2 * o + 1] += 1ll * lz1[o] * mi[mid - l + 1] % MOD * q1[r - mid] % MOD;
     85         if(q[2 * o + 1] >= MOD) q[2 * o + 1] -= MOD;
     86         lz1[2 * o] += lz1[o];
     87         if(lz1[2 * o] >= MOD) lz1[2 * o] -= MOD;
     88         lz1[2 * o + 1] += 1ll * lz1[o] * mi[mid - l + 1] % MOD;
     89         if(lz1[2 * o + 1] >= MOD) lz1[2 * o + 1] -= MOD;
     90         lz1[o] = 0;
     91     }
     92     if(lz2[o]) {
     93         q[2 * o] += 1ll * lz2[o] * q2[mid - l + 1] % MOD;
     94         if(q[2 * o] >= MOD) q[2 * o] -= MOD;
     95         q[2 * o + 1] += 1ll * lz2[o] * mi[mid - l + 1] % MOD * q2[r - mid] % MOD;
     96         if(q[2 * o + 1] >= MOD) q[2 * o + 1] -= MOD;
     97         q[2 * o + 1] += 1ll * lz2[o] * mi[mid - l + 1] % MOD * (mid - l + 1) % MOD * q1[r - mid] % MOD;
     98         if(q[2 * o + 1] >= MOD) q[2 * o + 1] -= MOD;
     99         lz2[2 * o] += lz2[o];
    100         if(lz2[2 * o] >= MOD) lz2[2 * o] -= MOD;
    101         lz2[2 * o + 1] += 1ll * lz2[o] * mi[mid - l + 1] % MOD;
    102         if(lz2[2 * o + 1] >= MOD) lz2[2 * o + 1] -= MOD;
    103         lz1[2 * o + 1] += 1ll * lz2[o] * mi[mid - l + 1] % MOD * (mid - l + 1) % MOD;
    104         if(lz1[2 * o + 1] >= MOD) lz1[2 * o + 1] -= MOD;
    105         lz2[o] = 0;
    106     }
    107     if(lz3[o]) {
    108         q[2 * o] += 1ll * lz3[o] * mi[r - mid] % MOD * q1[mid - l + 1] % MOD;
    109         if(q[2 * o] >= MOD) q[2 * o] -= MOD;
    110         q[2 * o + 1] += 1ll * lz3[o] * q1[r - mid] % MOD;
    111         if(q[2 * o + 1] >= MOD) q[2 * o + 1] -= MOD;
    112         lz3[2 * o] += 1ll * lz3[o] * mi[r - mid] % MOD;
    113         if(lz3[2 * o] >= MOD) lz3[2 * o] -= MOD;
    114         lz3[2 * o + 1] += lz3[o];
    115         if(lz3[2 * o + 1] >= MOD) lz3[2 * o + 1] -= MOD;
    116         lz3[o] = 0;
    117     }
    118     if(lz4[o]) {
    119         q[2 * o] += 1ll * lz4[o] * mi[r - mid] % MOD * q2[mid - l + 1] % MOD;
    120         if(q[2 * o] >= MOD) q[2 * o] -= MOD;
    121         q[2 * o] += 1ll * lz4[o] * mi[r - mid] % MOD * (r - mid) % MOD * q1[mid - l + 1] % MOD;
    122         if(q[2 * o] >= MOD) q[2 * o] -= MOD;
    123         q[2 * o + 1] += 1ll * lz4[o] * q2[r - mid] % MOD;
    124         if(q[2 * o + 1] >= MOD) q[2 * o + 1] -= MOD;
    125         lz4[2 * o] += 1ll * lz4[o] * mi[r - mid] % MOD;
    126         if(lz4[2 * o] >= MOD) lz4[2 * o] -= MOD;
    127         lz3[2 * o] += 1ll * lz4[o] * mi[r - mid] % MOD * (r - mid) % MOD;
    128         if(lz3[2 * o] >= MOD) lz3[2 * o] -= MOD;
    129         lz4[2 * o + 1] += lz4[o];
    130         if(lz4[2 * o + 1] >= MOD) lz4[2 * o + 1] -= MOD;
    131         lz4[o] = 0;
    132     }
    133 }
    134 inline void Do1(int l, int r, int o, int x, int y, int k, int st) {
    135     if(x <= l && r <= y) {
    136         k = 1ll * k * mi[st] % MOD; -- st;
    137         q[o] += 1ll * q2[r - l + 1] * k % MOD;
    138         if(q[o] >= MOD) q[o] -= MOD;
    139         lz2[o] += k;
    140         if(lz2[o] >= MOD) lz2[o] -= MOD;
    141         if(st) {
    142             q[o] += 1ll * q1[r - l + 1] * k % MOD * st % MOD;
    143             if(q[o] >= MOD) q[o] -= MOD;
    144             lz1[o] += 1ll * k * st % MOD;
    145             if(lz1[o] >= MOD) lz1[o] -= MOD;
    146         }
    147         return;
    148     }
    149     int mid = (l + r) / 2;
    150     pd(l, mid, r, o);
    151     if(y <= mid) {
    152         Do1(l, mid, 2 * o, x, y, k, st);
    153     }
    154     else if(x > mid) {
    155         Do1(mid + 1, r, 2 * o + 1, x, y, k, st);
    156     }
    157     else {
    158         Do1(l, mid, 2 * o, x, mid, k, st);
    159         Do1(mid + 1, r, 2 * o + 1, mid + 1, y, k, st + mid - x + 1);
    160     }
    161     q[o] = q[2 * o] + q[2 * o + 1];
    162     if(q[o] >= MOD) q[o] -= MOD;
    163 }
    164 inline void Do2(int l, int r, int o, int x, int y, int k, int st) {
    165     if(x <= l && r <= y) {
    166         k = 1ll * k * mi[st] % MOD; -- st;
    167         q[o] += 1ll * q2[r - l + 1] * k % MOD;
    168         if(q[o] >= MOD) q[o] -= MOD;
    169         lz4[o] += k;
    170         if(lz4[o] >= MOD) lz4[o] -= MOD;
    171         if(st) {
    172             q[o] += 1ll * q1[r - l + 1] * k % MOD * st % MOD;
    173             if(q[o] >= MOD) q[o] -= MOD;
    174             lz3[o] += 1ll * k * st % MOD;
    175             if(lz3[o] >= MOD) lz3[o] -= MOD;
    176         }
    177         return;
    178     }
    179     int mid = (l + r) / 2;
    180     pd(l, mid, r, o);
    181     if(y <= mid) {
    182         Do2(l, mid, 2 * o, x, y, k, st);
    183     } 
    184     else if(x > mid) {
    185         Do2(mid + 1, r, 2 * o + 1, x, y, k, st);
    186     }
    187     else {
    188         Do2(l, mid, 2 * o, x, mid, k, st + y - mid);
    189         Do2(mid + 1, r, 2 * o + 1, mid + 1, y, k, st);
    190     }
    191     q[o] = q[2 * o] + q[2 * o + 1];
    192     if(q[o] >= MOD) q[o] -= MOD;
    193 }
    194 inline int query(int l, int r, int o, int x, int y) {
    195     if(x <= l && r <= y) {
    196         if(q[o] < 0) {
    197             while(1);
    198         }
    199         return q[o];
    200     }
    201     int mid = (l + r) / 2, ret = 0;
    202     pd(l, mid, r, o);
    203     if(x <= mid) ret += query(l, mid, 2 * o, x, y);
    204     if(y > mid) ret += query(mid + 1, r, 2 * o + 1, x, y);
    205     if(ret >= MOD) ret -= MOD;
    206     return ret;
    207 }
    208 signed main() {
    209     n = read(), R = read(), Q = read();
    210     memset(head, -1, sizeof(head));
    211     for(int i = 1; i < n; ++ i) {
    212         int u = read(), v = read();
    213         add(u, v); add(v, u);
    214     }
    215     dfs1(1, 0);
    216     Top[1] = 1;
    217     dfs2(1, 0);
    218     init();
    219     while(Q --) {
    220         int op = read();
    221         if(op == 1) {
    222             int x = read(), y = read();
    223             int Ans = 0;
    224             while(Top[x] != Top[y]) {
    225                 if(h[Top[x]] < h[Top[y]]) swap(x, y);
    226                 Ans += query(1, n, 1, id[Top[x]], id[x]);
    227                 if(Ans >= MOD) Ans -= MOD;
    228                 x = fa[Top[x]];
    229             }
    230             if(h[x] > h[y]) swap(x, y);
    231             Ans += query(1, n, 1, id[x], id[y]);
    232             if(Ans >= MOD) Ans -= MOD;
    233             printf("%d
    ", (Ans + MOD) % MOD);
    234         }
    235         else {
    236             int X = read(), x = read(), y = read();
    237             X %= MOD;
    238             int LCA = lca(x, y), now = h[x] + h[y] - 2 * h[LCA] + 1;
    239             while(Top[y] != Top[LCA]) {
    240                 Do1(1, n, 1, id[Top[y]], id[y], X, now - (id[y] - id[Top[y]]));
    241                 now -= (id[y] - id[Top[y]] + 1);
    242                 y = fa[Top[y]];
    243             }
    244             if(h[LCA] < h[y]) {
    245                 Do1(1, n, 1, id[LCA] + 1, id[y], X, now - (id[y] - id[LCA] - 1));
    246             }
    247             now = 1;
    248             while(Top[x] != Top[LCA]) {
    249                 Do2(1, n, 1, id[Top[x]], id[x], X, now);
    250                 now += (id[x] - id[Top[x]]) + 1;
    251                 x = fa[Top[x]];
    252             }
    253             if(h[LCA] <= h[x]) {
    254                 Do2(1, n, 1, id[LCA], id[x], X, now);
    255             }
    256         }
    257     }
    258 }
  • 相关阅读:
    消费券
    .net Core 用户登入身份验证简单的demo
    微信阅读. 电脑版. 标记上一页阅读到的位置. 油猴(Tampermonkey)插件
    Docker.控制台程序.发布
    Docker.容器管理
    Docker.镜像管理
    RestSharp 加号变空格 + HTTP 请求
    在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误
    数据库.Sqlserver.重建索引
    数据库.索引Vs树
  • 原文地址:https://www.cnblogs.com/iamqzh233/p/9478563.html
Copyright © 2011-2022 走看看