zoukankan      html  css  js  c++  java
  • HDU 5039 Hilarity

    题意:一棵树n个结点,每条边有0.1两种权值,每次询问权值为奇数的路径数目,或者改变某一条边的权值。

    分析:这个题目很巧妙低利用了异或和的特性,dfs得到每个点到根结点的权值异或和,然后奇数则为1,偶数为0,异或和为0和1的点组成的路径权值和一定为奇数,询问结果就是0个数和1个数乘积2倍。

    代码:

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <vector>
      4 #include <map>
      5 #include <cstring>
      6 #include <cmath>
      7 #include <algorithm>
      8 #include <set>
      9 #define pb push_back
     10 #define mp make_pair
     11 
     12 #define lson   l, m, rt<<1
     13 #define rson   m+1, r, rt<<1|1
     14 #define sz(x) ((int)((x).size()))
     15 #define pb push_back
     16 #define in freopen("data.txt", "r", stdin);
     17 #define bug(x) printf("Line : %u >>>>>>
    ", (x));
     18 #define inf 0x0f0f0f0f
     19 using namespace std;
     20 typedef pair<int, int> PII;
     21 typedef map<string, int> MPS;
     22 typedef long long LL;
     23 
     24 const int maxn = 30000 + 100;
     25 MPS mps;
     26 
     27 struct Edge {
     28     int u, v, c;
     29     Edge() {}
     30     Edge(int u, int v, int c):u(u), v(v), c(c) {}
     31 };
     32 vector<Edge> edges;
     33 vector<int> g[maxn];
     34 
     35 int n, m, q, cnt;
     36 int le[maxn], ri[maxn];
     37 
     38 int idx(char *s) {
     39     if(mps.count(s) == false)
     40         mps[s] = ++cnt;
     41     return mps[s];
     42 }
     43 
     44 void add(int u, int v, int c) {
     45     edges.pb(Edge(u, v, c));
     46     edges.pb(Edge(v, u, c));
     47     m = edges.size();
     48     g[u].pb(m-2);
     49     g[v].pb(m-1);
     50 }
     51 char sa[20], sb[20];
     52 int cover[maxn<<2], val[maxn], dep[maxn], ans[maxn<<2];
     53 void PushUp(int rt) {
     54     ans[rt] = ans[rt<<1]+ans[rt<<1|1];
     55 }
     56 //线段树的每个结点要初始化!!!!
     57 
     58 void PushDown(int l, int r, int rt) {
     59     int m = (l+r)>>1;
     60     if(cover[rt]) {
     61         cover[rt<<1] ^= 1;
     62         cover[rt<<1|1] ^= 1;
     63         ans[rt<<1] = m-l+1-ans[rt<<1];
     64         ans[rt<<1|1] = r-m-ans[rt<<1|1];
     65         cover[rt] = 0;
     66     }
     67 }
     68 void build(int l, int r, int rt) {
     69     if(l == r) {
     70         cover[rt] = 0;
     71         ans[rt] = val[l];
     72         return;
     73     }
     74     cover[rt] = 0;
     75     int m = (l+r)>>1;
     76     build(lson);
     77     build(rson);
     78     PushUp(rt);
     79 }
     80 void update(int l, int r, int rt, int L, int R) {
     81     if(L <= l && R >= r) {
     82         cover[rt] ^= 1;
     83         ans[rt] = r-l+1-ans[rt];
     84         return;
     85     }
     86 
     87     int m = (l+r)>>1;
     88     PushDown(l, r, rt);
     89     if(L <= m)
     90         update(lson, L, R);
     91     if(R > m)
     92         update(rson, L, R);
     93     PushUp(rt);
     94 }
     95 void dfs(int u, int fa, int va) {
     96     dep[u] = dep[fa] + 1;
     97     le[u] = ++cnt;
     98     val[cnt] = va;
     99     for(int i = 0; i < (int)g[u].size(); i++) {
    100         Edge e = edges[g[u][i]];
    101         int v = e.v;
    102         int c = e.c;
    103         if(v == fa) continue;
    104         dfs(v, u, c^va);
    105     }
    106     ri[u] = cnt;
    107 }
    108 int main() {
    109 
    110     int T;
    111     int kase = 0;
    112     for(int t = scanf("%d", &T); t <= T; t++) {
    113         scanf("%d", &n);
    114         mps.clear();
    115         cnt = 0;
    116         edges.clear();
    117         for(int i = 1; i <= n; i++) {
    118             g[i].clear();
    119             scanf("%s", sa);
    120             idx(sa);
    121         }
    122         for(int i = 0; i < n-1; i++) {
    123             int c, u, v;
    124             scanf("%s%s%d", sa, sb, &c);
    125             u = idx(sa);
    126             v = idx(sb);
    127             add(u, v, c);
    128         }
    129         scanf("%d", &q);
    130         printf("Case #%d:
    ", ++kase);
    131         cnt = 0;
    132         dfs(1, 0, 0);
    133         build(1, n, 1);
    134         LL res = 0;
    135         while(q--) {
    136             scanf("%s", sa);
    137             if(sa[0] == 'Q') {
    138                 res = (LL)(n-ans[1])*ans[1]*2;
    139                 printf("%I64d
    ", res);
    140             } else {
    141                 int x;
    142                 scanf("%d", &x);
    143                 x--;
    144                 x <<= 1;
    145                 int u = edges[x].u;
    146                 int v = edges[x].v;
    147                 if(dep[u] < dep[v]) swap(u, v);
    148                 update(1, n, 1, le[u], ri[u]);
    149             }
    150         }
    151     }
    152     return 0;
    153 }
    View Code

     当然也有一种更复杂的方法,同Qtree4,可以拿来练手,感觉有点无聊。

  • 相关阅读:
    MySQL 5.7 多主一从实现
    从 MySQL 全备的 SQL 文件中抽离出某张表的数据
    KUBERNETES 03:Pod 资源清单
    KUBERNETES 02:基本操作命令
    KUBERNETES 01:说明与安装
    DOCKER 08:搭建本地镜像仓库 Harbor
    DOCKER 07:docker swarm
    DOCKER 06:docker compose
    DOCKER 05:数据持久化
    DOCKER 04:容器资源限制和网络原理
  • 原文地址:https://www.cnblogs.com/rootial/p/4047012.html
Copyright © 2011-2022 走看看