zoukankan      html  css  js  c++  java
  • UOJ #58 糖果公园

    Candyland 有一座糖果公园,公园里不仅有美丽的风景、好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园玩。

    糖果公园的结构十分奇特,它由 n 个游览点构成,每个游览点都有一个糖果发放处,我们可以依次将游览点编号为 1 至 n。有 n1条双向道路连接着这些游览点,并且整个糖果公园都是连通的,即从任何一个游览点出发都可以通过这些道路到达公园里的所有其它游览点。

    糖果公园所发放的糖果种类非常丰富,总共 m 种,它们的编号依次为 1 至 m。每一个糖果发放处都只发放某种特定的糖果,我们用 ci 来表示 i 号游览点的糖果。

    来到公园里游玩的游客都不喜欢走回头路,他们总是从某个特定的游览点出发前往另一个特定的游览点,并游览途中的景点,这条路线一定是唯一的。他们经过每个游览点,都可以品尝到一颗对应种类的糖果。

    大家对不同类型的糖果的喜爱程度都不尽相同。根据游客们的反馈打分,我们得到了糖果的美味指数,第 i 种糖果的美味指数为 vi。另外,如果一位游客反复地品尝同一种类的糖果,他肯定会觉得有一些腻。根据量化统计,我们得到了游客第 i 次品尝某类糖果的新奇指数 wi,如果一位游客第 i 次品尝第 j 种糖果,那么他的愉悦指数 H 将会增加对应的美味指数与新奇指数的乘积,即 vjwi。这位游客游览公园的愉悦指数最终将是这些乘积的和。

    当然,公园中每个糖果发放点所发放的糖果种类不一定是一成不变的。有时,一些糖果点所发放的糖果种类可能会更改(也只会是 m 种中的一种),这样的目的是能够让游客们总是感受到惊喜。

    糖果公园的工作人员小 A 接到了一个任务,那就是根据公园最近的数据统计出每位游客游玩公园的愉悦指数。但数学不好的小 A 一看到密密麻麻的数字就觉得头晕,作为小 A 最好的朋友,你决定帮他一把。

    输入格式

    第一行包含三个正整数 n,m,q,分别表示游览点个数、糖果种类数和操作次数。

    第二行包含 mm 个正整数 v1,v2,,vm。

    第三行包含 nn 个正整数 w1,w2,,wn。

    第四行到第 n+2 行,每行包含两个正整数 ai,bi,表示这两个游览点之间有路径可以直接到达。

    第 n+3 行包含 n 个正整数 c1,c2,,cn。

    接下来 q 行,每行包含三个整数 t,x,y,表示一次操作:

    若 t 为 0,则 1xn,1ym,表示编号为 x 的游览点发放的糖果类型改为 y;

    若 t 为 1,则 1x,yn,表示对出发点为 x,终止点为 y 的路线询问愉悦指数。

    输出格式

    按照输入的先后顺序,对于每个 t 为 1 的操作输出一行,用一个正整数表示答案。

    样例一

    input

    4 3 5
    1 9 2
    7 6 5 1
    2 3
    3 1
    3 4
    1 2 3 2
    1 1 2
    1 4 2
    0 2 1
    1 1 2
    1 4 2
    
    

    output

    84
    131
    27
    84
    
    

    限制与约定

    对于所有的数据,1vi,wi106,1ai,bin,1cim,w1,w2,,wn 是非递增序列,即对任意 1<in,满足 wiwi1。

    测试点编号nmq其它限制
    1 20 20 20
    2 2000 2000 2000
    3 10000 10000 10000
    4 80000 100 80000 没有修改操作;给出的图构成一条链
    5 90000 100 90000
    6 80000 80000 80000 没有修改操作
    7 90000 90000 90000
    8 80000 80000 80000 给出的图构成一条链
    9 90000 90000 90000
    10 100000 100000 100000

    祝大家一遍 AC,求不虐萌萌哒测评机!

    时间限制8s

    空间限制512MB

    真是卡OJ神题,我这道题加起来大概卡了UOJ有10min

    树上带修莫队,按照DFS序分块或者王室联邦都行,好像王室联邦会更快

    移动端点就是修改两条链,只要不断的往LCA爬,将路径上的点存在性取反就行了,不用讨论,但要记得LCA只翻转一次

    记得排序的时候按照所属块排序,左右端点都是,不要写出右端点直接比较这种东西来了

      1 #include <iostream>
      2 #include <cstdlib>
      3 #include <cstdio>
      4 #include <algorithm>
      5 #include <string>
      6 #include <cstring>
      7 #include <cmath>
      8 #include <map>
      9 #include <stack>
     10 #include <set>
     11 #include <vector>
     12 #include <queue>
     13 #include <time.h>
     14 #define eps 10e-7
     15 #define INF 0x3f3f3f3f
     16 #define MOD 1000000007
     17 #define rep0(j,n) for(int j=0;j<n;++j)
     18 #define rep1(j,n) for(int j=1;j<=n;++j)
     19 #define pb push_back
     20 #define set0(n) memset(n,0,sizeof(n))
     21 #define ll long long
     22 #define iter(i,v) for(edge *i = head[v];i;i = i->nxt)
     23 #define max(a,b) (a>b?a:b)
     24 #define min(a,b) (a<b?a:b)
     25 //#define OJ
     26 using namespace std;
     27 char BUF[10000000], *buf;
     28 int read() {
     29     int x = 0;
     30     while (!isdigit(*buf)) { buf++; }
     31     while (isdigit(*buf)) { x = x * 10 + *buf++ - '0'; }
     32     return x;
     33 }
     34 char get_ch() {
     35     char c = getchar();
     36     while (!isalpha(c)) c = getchar();
     37     return c;
     38 }
     39 const int MAXINT = 100010;
     40 const int MAXNODE = 100010;
     41 ll ans, w[MAXNODE], ps_w[MAXINT], qa[MAXINT];
     42 int st[18][MAXNODE*4]={},seq[MAXNODE*4]={},cnt_seq=0,fst[MAXNODE]={},max_p2[262145]={},no[MAXNODE],stk[MAXNODE],top=0,cnt_bl=1;
     43 int dfn[MAXNODE]={}, cnt_dfn=0, bl[MAXNODE]={}, n=0, m=0, v[MAXINT]={}, c[MAXNODE]={}, dep[MAXNODE]={}, in_ans[MAXNODE]={}, fa[MAXNODE]={}, cnt_eg, sz_b, q, cnt_cd[MAXINT]={}, cnt_mdf = -1, cnt_qr;
     44 struct edge {
     45     int u, v;
     46     edge *nxt;
     47     edge(int _u, int _v, edge *_nxt) {
     48         u = _u; v = _v; nxt = _nxt;
     49     }
     50     edge() {}
     51 }*head[MAXNODE], mp[MAXNODE * 2];
     52 struct op {
     53     int tp, x, y, lstc, no;
     54     op(int _x, int _y) {
     55         tp = 1;
     56         x = _x;
     57         y = _y;
     58     }
     59     op(int lst, int _x, int _y, int _no) {
     60         lstc = lst;
     61         tp = 0;
     62         //if (dfn[_x] > dfn[_y]) swap(_x, _y);
     63         x = _x;
     64         y = _y;
     65         no = _no;
     66     }
     67     op() {}
     68 }mdf[MAXINT], qr[MAXINT];
     69 int cmp(const op &a, const op &b) {
     70     if(bl[a.x]==bl[b.x]&&bl[a.y]==bl[b.y]) {if(bl[a.x]&1)return a.lstc<b.lstc; else return a.lstc>b.lstc;}
     71     if(bl[a.x]==bl[b.x])  {if(bl[a.x]&1) return bl[a.y]<bl[b.y]; else return bl[a.y]>bl[b.y];}
     72     return bl[a.x] < bl[b.x];
     73 }
     74 inline void rev(int);
     75 inline void add(int);
     76 inline void remove(int);
     77 inline void add(op&);
     78 inline void remove(op&);
     79 inline void add_edge(int, int);
     80 inline void get_st();
     81 inline void get_input();
     82 inline void work();
     83 inline void solve(int,int);
     84 inline int get_lca(int, int);
     85 //inline void dfs(int, int);
     86 inline int dfs(int, int);
     87 int main() {
     88     //freopen("in.txt", "r", stdin);
     89     //freopen("out.tle", "w", stdout);
     90     for(int i=0;i<=17;i++){
     91         for (int j=(1<<i);j<(1<<(i+1));j++){
     92             max_p2[j]=i;
     93         }
     94     }
     95     get_input();
     96     get_st();
     97     work();
     98     //printf("%d
    ",clock());
     99     return 0;
    100 }
    101 inline void rev(int p) {
    102     if (in_ans[p]) {
    103         in_ans[p] = 0;
    104         ans -= w[cnt_cd[c[p]]] * v[c[p]];
    105         cnt_cd[c[p]]--;
    106     }
    107     else {
    108         in_ans[p] = 1;
    109         cnt_cd[c[p]]++;
    110         ans += w[cnt_cd[c[p]]] * v[c[p]];
    111     }
    112 }
    113 inline void solve(int p1,int p2){
    114     while(p1!=p2){
    115         dep[p1]>dep[p2]?(rev(p1),p1=fa[p1]):(rev(p2),p2=fa[p2]);
    116     }
    117 }
    118 inline void work() {
    119     rep0(i,cnt_qr) if(bl[qr[i].x]<bl[qr[i].y]) swap(qr[i].x,qr[i].y);
    120     sort(qr, qr + cnt_qr, cmp);
    121     int l, r, pl, pr, lca, lca2, pq = -1;
    122     for (int i = pq; i > qr[0].lstc; i--) {
    123         remove(mdf[i]);
    124     }
    125     for (int i = pq + 1; i <= qr[0].lstc; i++) {
    126         add(mdf[i]);
    127     }
    128     pl = l = qr[0].x;
    129     pr = r = qr[0].y;
    130     lca = get_lca(l, r);
    131     solve(pl,pr);
    132     rev(lca);
    133     qa[qr[0].no] = ans;
    134     pq = qr[0].lstc;
    135     rep1(i, cnt_qr - 1) {
    136         for (int j = pq; j > qr[i].lstc; j--) {
    137             remove(mdf[j]);
    138         }
    139         for (int j = pq + 1; j <= qr[i].lstc; j++) {
    140             add(mdf[j]);
    141         }
    142         lca = get_lca(l, r);
    143         lca2 = get_lca(qr[i].x, qr[i].y);
    144         solve(l,qr[i].x);
    145         solve(r,qr[i].y);
    146         rev(lca);
    147         rev(lca2);
    148         l = qr[i].x; r = qr[i].y;
    149         pq = qr[i].lstc;
    150         qa[qr[i].no] = ans;
    151     }
    152     rep0(i, cnt_qr) {
    153         printf("%lld
    ", qa[i]);
    154     }
    155 }
    156 inline void add_edge(int u, int v) {
    157     mp[cnt_eg] = edge(u, v, head[u]);
    158     head[u] = &mp[cnt_eg++];
    159     mp[cnt_eg] = edge(v, u, head[v]);
    160     head[v] = &mp[cnt_eg++];
    161 }
    162 inline void get_input() {
    163     int tp, _u, _v;
    164     BUF[fread(BUF, 1, 10000000, stdin)]=0;
    165     buf = BUF;
    166     n = read(); m = read(); q = read();
    167     sz_b = ceil(pow(n, 2.0 / 3.0))/2+1;
    168     rep1(i, m) v[i] = read();
    169     rep1(i, n) w[i] = read();
    170     rep1(i, n) ps_w[i] += ps_w[i - 1] + w[i];
    171     rep1(i, n - 1) {
    172         _u = read(); _v = read();
    173         add_edge(_u, _v);
    174     }
    175     dfs(1, 0);
    176     while(top) bl[stk[--top]]=cnt_bl-1;
    177     rep1(i, n) c[i] = read();
    178     rep0(i, q) {
    179         tp = read(); _u = read(); _v = read();
    180         if (tp == 1) qr[cnt_qr] = op(cnt_mdf, _u, _v, cnt_qr), cnt_qr++;
    181         else mdf[++cnt_mdf] = op(_u, _v);
    182     }
    183 }
    184 /*inline void dfs(int p, int f) {
    185     fa[p] = f;
    186     dep[p] = dep[f] + 1;
    187     no[cnt_dfn]=p;
    188     dfn[p] = ++cnt_dfn;
    189     bl[p] = dfn[p] / sz_b;
    190     fst[p] = cnt_seq;
    191     seq[cnt_seq++]=dfn[p];
    192     iter(i, p) {
    193         if (i->v == f) continue;
    194         dfs(i->v, p);
    195         seq[cnt_seq++]=dfn[p];
    196     }
    197 }*/
    198 inline int dfs(int p, int f) {
    199     int sz=0,bt=top;
    200     fa[p] = f;
    201     dep[p] = dep[f] + 1;
    202     no[cnt_dfn]=p;
    203     dfn[p] = ++cnt_dfn;
    204     //bl[p] = dfn[p] / sz_b;
    205     fst[p] = cnt_seq;
    206     seq[cnt_seq++]=dfn[p];
    207     iter(i, p) {
    208         if (i->v == f) continue;
    209         sz+=dfs(i->v, p);
    210         seq[cnt_seq++]=dfn[p];
    211         if (top-bt>=sz_b){
    212             while(top!=bt) bl[stk[--top]]=cnt_bl;
    213             cnt_bl++,sz=0;
    214         }
    215     }
    216     stk[top++]=p;
    217     return sz+1;
    218 }
    219 inline void get_st() {
    220     rep0(i,cnt_seq) st[0][i]=seq[i];
    221     for (int i = 1; i <= 17; i++)
    222         for (int j = 0; j < cnt_seq-(1<<i)+1; j++)
    223             st[i][j] = min(st[i-1][j],st[i-1][j+(1<<(i-1))]);
    224 }
    225 inline int get_lca(int x, int y) {
    226     x=fst[x];y=fst[y];
    227     if(x>y) swap(x,y);
    228     int l = y-x+1;
    229     return no[min(st[max_p2[l]][x],st[max_p2[l]][y-(1<<max_p2[l])+1])-1];
    230 }
    231 inline void remove(int p) {
    232     ans -= w[cnt_cd[p]] * v[p];
    233     cnt_cd[p]--;
    234 }
    235 inline void add(int p) {
    236     cnt_cd[p]++;
    237     ans += w[cnt_cd[p]] * v[p];
    238 }
    239 inline void add(op& cg) {
    240     //int f = get_lca(l, r), f1 = get_lca(l, cg.x), f2 = get_lca(r, cg.x);
    241     cg.lstc = c[cg.x];
    242     c[cg.x] = cg.y;
    243     if(in_ans[cg.x]){
    244     //if ((f == f1&&f2 == cg.x) || (f == f2&&f1 == cg.x)) {
    245         ans -= w[cnt_cd[cg.lstc]] * v[cg.lstc];
    246         cnt_cd[cg.lstc]--;
    247         cnt_cd[cg.y]++;
    248         ans += w[cnt_cd[cg.y]] * v[cg.y];
    249     }
    250 }
    251 inline void remove(op& cg) {
    252     //int f = get_lca(l, r), f1 = get_lca(l, cg.x), f2 = get_lca(r, cg.x);
    253     c[cg.x] = cg.lstc;
    254     //if ((f == f1&&f2 == cg.x) || (f == f2&&f1 == cg.x)) {
    255     if(in_ans[cg.x]){
    256         ans -= w[cnt_cd[cg.y]] * v[cg.y];
    257         cnt_cd[cg.y]--;
    258         cnt_cd[cg.lstc]++;
    259         ans += w[cnt_cd[cg.lstc]] * v[cg.lstc];
    260     }
    261 }
    许愿弥生改二
  • 相关阅读:
    c++ struct 使用
    c++数组、字符串操作
    c++ List、Vector、Stack、Queue使用
    十三、哈希表
    十二、234树
    十一、红黑树
    十、哈夫曼编码
    九、二叉树
    八、高级排序
    七、递归
  • 原文地址:https://www.cnblogs.com/LoveYayoi/p/6745435.html
Copyright © 2011-2022 走看看