zoukankan      html  css  js  c++  java
  • 2013多校训练赛第一场 总结

    http://acm.hdu.edu.cn/listproblem.php?vol=37

    hdu 4600~4610 2013HDU多校训练第一场

      这次的组队训练好没状态,居然敲几题水题都搞了2个多种。最后我们队做出了4题,排在41名。

    不太想写东西,直接上题解了:

    Problem - 4604

      这题做法其实还没想到,不过写出了一个能过目前所有数据的代码(比赛的时候数据更水,几乎算不出正确答案的代码都能过):

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <map>
     6 
     7 using namespace std;
     8 
     9 const int N = 111111;
    10 
    11 int rec[N], dp1[N], dp2[N], same[N];
    12 int s[N], top;
    13 
    14 int find1(int x) {
    15     int l = 0, r = top, m, mk = -1;
    16     while (l <= r) {
    17         m = l + r >> 1;
    18         if (s[m] >= x) mk = m, l = m + 1;
    19         else r = m - 1;
    20     }
    21     return mk;
    22 }
    23 
    24 void DP1(int n) {
    25     top = -1;
    26     for (int i = n - 1; i >= 0; i--) {
    27         int pos = find1(rec[i]) + 1;
    28         dp1[i] = pos + 1;
    29         if (pos > top) s[++top] = rec[i];
    30         else s[pos] = max(s[pos], rec[i]);
    31     }
    32 }
    33 
    34 void DP2(int n) {
    35     top = -1;
    36     for (int i = n - 1; i >= 0; i--) {
    37         int pos = (int) (upper_bound(s, s + top + 1, rec[i]) - s);
    38         dp2[i] = pos + 1;
    39         if (pos > top) s[++top] = rec[i];
    40         else s[pos] = min(s[pos], rec[i]);
    41         same[i] = upper_bound(s, s + top + 1, rec[i]) - lower_bound(s, s + top + 1, rec[i]);
    42     }
    43 }
    44 
    45 int main() {
    46     int n, T;
    47     scanf("%d", &T);
    48     while (T-- && ~scanf("%d", &n)) {
    49         for (int i = 0; i < n; i++) scanf("%d", &rec[i]);
    50         DP1(n);
    51         DP2(n);
    52         int ans = 0;
    53         //for (int i = 0; i < n; i++) cout << dp1[i] << ' '; cout << endl;
    54         //for (int i = 0; i < n; i++) cout << dp2[i] << ' '; cout << endl;
    55         //for (int i = 0; i < n; i++) cout << same[i] << ' '; cout << endl;
    56         for (int i = 0; i < n; i++) ans = max(ans, dp1[i] + dp2[i] - same[i]);
    57         printf("%d
    ", ans);
    58     }
    59     return 0;
    60 }
    View Code

      这里的做法是计算LIS了,然后去掉重复。可是根据题意,对于下面一组数据是应该输出5的:

    5

    1 1 11 1 1

      不管了,先放着。

    Problem - 4602

      这题是用插板法,排列组合的题。队友出的,注意的是k有可能大于n:

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <map>
     6 #include <queue>
     7 #include <stack>
     8 #include <set>
     9 
    10 using namespace std;
    11 
    12 typedef long long LL;
    13 const LL MOD = 1e9 + 7;
    14 
    15 LL powmod(LL a, LL b) {
    16     LL ret = 1;
    17     while (b > 0) {
    18         if (b & 1) ret *= a, ret %= MOD;
    19         a *= a, a %= MOD;
    20         b >>= 1;
    21     }
    22     return ret;
    23 }
    24 
    25 int main() {
    26     int T;
    27     LL n, k;
    28     cin >> T;
    29     while (T-- && ~scanf("%I64d%I64d", &n, &k)) {
    30         if (n == k) puts("1");
    31         else if (n == k + 1) puts("2");
    32         else if (k < n){
    33             printf("%I64d
    ", (powmod(2, n - k) + (n - k - 1) * powmod(2, n - k - 2)) % MOD);
    34         } else puts("0");
    35     }
    36     return 0;
    37 }
    View Code

    Problem - 4608

      这题是最水的了,不过真的很没状态啊,居然搞很久才过,幸亏1y了。

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <map>
     6 #include <queue>
     7 #include <stack>
     8 #include <set>
     9 
    10 using namespace std;
    11 
    12 const int N = 111111;
    13 
    14 char str[N];
    15 int main() {
    16     int T;
    17     cin >> T;
    18     while (T-- && cin >> str) {
    19         int len = strlen(str), pos;
    20         int sum = 0;
    21         for (int i = 0; i < len; i++) sum += str[i] - '0';
    22         sum %= 10;
    23         sum = 10 - sum;
    24         if (str[len - 1] - '0' + sum < 10) {
    25             str[len - 1] += sum;
    26             puts(str);
    27         } else {
    28             str[len - 1] = '0';
    29             pos = len - 2;
    30             while (pos >= 0 && str[pos] == '9') str[pos--] = '0';
    31             if (pos < 0) {
    32                 putchar('1');
    33                 str[len - 1] = 0;
    34                 printf("%s", str);
    35                 puts("9");
    36             } else {
    37                 sum = 0;
    38                 str[pos]++;
    39                 for (int i = 0; i < len; i++) sum += str[i] - '0';
    40                 sum %= 10;
    41                 str[len - 1] += (10 - sum) % 10;
    42                 puts(str);
    43             }
    44         }
    45     }
    46     return 0;
    47 }
    View Code

      之后会陆续补充题解!

      这次真的很没状态,代码各种没平时的飘逸。。需要调整一下!

    UPD:

     Problem - 4609

      FFT,比赛的时候想到了比较接近的模型,可惜没有继续想下去。这里我们可以通过FFT达到快速完成多项式乘法的效果。最后debug了好久,多次发现因为有些变量没有用long long,wa了几次。

      题意十分简单,就是给出若干边,问可以构成三角形的概率是多少。这里可以先求出反面例子,也就是两条边a+b<=c的情况,就是这里用了FFT,然后就是用全部情况减去枚举的每一个结果就行了。

    带debug的代码如下:

      1 #define code 1
      2 
      3 #if (code == 1)
      4 
      5 #include <cstdio>
      6 #include <cstring>
      7 #include <iostream>
      8 #include <algorithm>
      9 #include <cmath>
     10 
     11 using namespace std;
     12 
     13 const int N = 1 << 17;
     14 const double PI = acos(-1.0);
     15 
     16 struct Vir {
     17     double r, i;
     18     Vir() {}
     19     Vir(double r, double i) : r(r), i(i) {}
     20     Vir operator + (Vir &x) { return Vir(r + x.r, i + x.i);}
     21     Vir operator - (Vir &x) { return Vir(r - x.r, i - x.i);}
     22     Vir operator * (Vir &x) { return Vir(r * x.r - i * x.i, r * x.i + i * x.r);}
     23 } rev[N << 1], v1[N << 1], v2[N << 1];
     24 
     25 const int M = 22;
     26 int ep[M];
     27 double base[M], cosb[M], sinb[M];
     28 
     29 void PRE() {
     30     ep[0] = 1;
     31     for (int i = 1; i < M; i++) ep[i] = ep[i - 1] << 1;
     32     for (int i = 0; i < M - 1; i++) base[i] = 2 * PI / ep[i + 1];
     33     for (int i = 0; i < M - 1; i++) sinb[i] = sin(base[i]), cosb[i] = cos(base[i]);
     34 }
     35 
     36 inline int revbit(int x, int l) {
     37     int ret = 0;
     38     while (l--) ret <<= 1, ret |= x & 1, x >>= 1;
     39     return ret;
     40 }
     41 
     42 inline void reverse(Vir *a, int len) {
     43     int bits = (int) ceil(log((double) len) / log(2.0));
     44     for (int i = 0; i < len; i++) rev[revbit(i, bits)] = a[i];
     45     for (int i = 0; i < len; i++) a[i] = rev[i];
     46 }
     47 
     48 const Vir unit = Vir(1.0, 0.0);
     49 
     50 void fft(Vir *a, int len, bool idft) {
     51     Vir u, t;
     52     int bits = (int) ceil(log((double) len) / log(2.0));
     53     reverse(a, len);
     54     for (int i = 0; i < bits; i++) {
     55         Vir wi, w;
     56         wi.r = cosb[i];
     57         wi.i = idft ? -sinb[i] : sinb[i];
     58         for (int k = 0; k < len; k+= ep[i + 1]) {
     59             w = unit;
     60             for (int j = 0; j < ep[i]; j++) {
     61                 t = w * a[k + j + ep[i]];
     62                 u = a[k + j];
     63                 a[k + j] = u + t;
     64                 a[k + j + ep[i]] = u - t;
     65                 w = w * wi;
     66             }
     67         }
     68     }
     69     if (idft) for (int i = 0; i < len; i++) a[i].r /= len;
     70 }
     71 
     72 void cal(Vir *a, Vir *b, int len) {
     73     fft(a, len, 0);
     74     fft(b, len, 0);
     75     for (int i = 0; i < len; i++) a[i] = a[i] * b[i];
     76     fft(a, len, 1);
     77 }
     78 
     79 int rec[N];
     80 typedef long long LL;
     81 LL cnt[N << 1];
     82 
     83 bool test(int a, int b, int c) {
     84     if (a + b <= c) return false;
     85     if (a + c <= b) return false;
     86     if (b + c <= a) return false;
     87     return true;
     88 }
     89 
     90 double BF(int n) {
     91     int cnt = 0;
     92     for (int i = 0; i < n; i++) {
     93         for (int j = i + 1; j < n; j++) {
     94             for (int k = j + 1; k < n; k++) {
     95                 cnt += test(rec[i], rec[j], rec[k]);
     96             }
     97         }
     98     }
     99     return 6.0 * cnt / (n * (n - 1) * (n - 2));
    100 }
    101 
    102 int main() {
    103 //    freopen("in", "r", stdin);
    104     int n, x, T;
    105     PRE();
    106     cin >> T;
    107     while (T-- && cin >> n) {
    108         memset(v1, 0, sizeof(v1));
    109         memset(v2, 0, sizeof(v2));
    110         int mx = 0;
    111         for (int i = 0; i < n; i++) {
    112             scanf("%d", &x);
    113             rec[i] = x;
    114             v1[x].r += 1.0;
    115             v2[x].r += 1.0;
    116             mx = max(x, mx);
    117         }
    118         mx++;
    119         int len = 0;
    120         while (ep[len] < mx) len++;
    121         len = ep[len + 1];
    122         cal(v1, v2, len);
    123 //        cout << len << endl;
    124         LL tt = (LL) n * (n - 1) * (n - 2) / 6, ans = tt;
    125 //        cout << tt << endl;
    126         for (int i = 0; i < len; i++) cnt[i] = (LL) floor(v1[i].r + 0.5);
    127 //        for (int i = 0; i < 16; i++) cout << i << ' ' << v1[i].r << endl;
    128         for (int i = 0; i < n; i++) cnt[rec[i] << 1]--;
    129 //        for (int i = 0; i < 16; i++) cout << i << ' ' << cnt[i] << endl;
    130         for (int i = 0; i < len; i++) {
    131             cnt[i] >>= 1;
    132             cnt[i] += cnt[i - 1];
    133         }
    134         for (int i = 0; i < n; i++) ans -= cnt[rec[i]];
    135 //        cout << ans << endl;
    136         printf("%.7f
    ", ans * 1.0 / tt);
    137 //        double ansbf;
    138 //        printf("%.7f BruceForce~~~
    ", ansbf = BF(n));
    139 //        if (fabs(ans * 1.0 / tt - ansbf) > 1e-7) {
    140 //            freopen("out", "w", stdout);
    141 //            puts("1");
    142 //            cout << n << endl;
    143 //            for (int i = 0; i < n; i++) cout << rec[i] << ' '; cout << endl;
    144 //            puts("WTF?!?!?!?!?!");
    145 //            break;
    146 //        }
    147     }
    148     return 0;
    149 }
    150 
    151 #else
    152 
    153 #include <cstdio>
    154 #include <cstring>
    155 #include <iostream>
    156 #include <algorithm>
    157 #include <ctime>
    158 #include <cmath>
    159 
    160 using namespace std;
    161 
    162 const int T = 1000;
    163 const int MAXN = 1000;
    164 const int DIF = 10;
    165 const int MAXNUM = 100000;
    166 
    167 int main() {
    168     freopen("in", "w", stdout);
    169     cout << 1 << endl << 100000 << endl;
    170     for (int i = 0; i < 100000; i++) cout << rand() % 2 + 1 << ' '; cout << endl;
    171 //    int t = T >> 2;
    172 //    srand(time(0));
    173 //    cout << T << endl;
    174 //    while (t--) {
    175 //        int n = MAXN - DIF + 1 + rand() % DIF;
    176 //        cout << n << endl;
    177 //        while (n--) cout << rand() % 10 + 1 << ' ';
    178 //        cout << endl;
    179 //    }
    180 //    t = T >> 2;
    181 //    while (t--) {
    182 //        int n = MAXN - DIF + 1 + rand() % DIF;
    183 //        cout << n << endl;
    184 //        while (n--) cout << rand() % 100 + 1 << ' ';
    185 //        cout << endl;
    186 //    }
    187 //    t = T >> 2;
    188 //    while (t--) {
    189 //        int n = MAXN - DIF + 1 + rand() % DIF;
    190 //        cout << n << endl;
    191 //        while (n--) cout << rand() % 1000 + 1 << ' ';
    192 //        cout << endl;
    193 //    }
    194 //    t = T >> 2;
    195 //    while (t--) {
    196 //        int n = MAXN - DIF + 1 + rand() % DIF;
    197 //        cout << n << endl;
    198 //        while (n--) cout << rand() % MAXNUM + 1 << ' ';
    199 //        cout << endl;
    200 //    }
    201     return 0;
    202 }
    203 
    204 #endif
    View Code

      上面的代码写了个暴力对拍,可惜最后还是想到数据,然后找到错误的数据,最后修改过来通过的。

    代码如下:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <cmath>
      6 
      7 using namespace std;
      8 
      9 const int N = 1 << 17;
     10 const double PI = acos(-1.0);
     11 
     12 struct Vir {
     13     double r, i;
     14     Vir() {}
     15     Vir(double r, double i) : r(r), i(i) {}
     16     Vir operator + (Vir &x) { return Vir(r + x.r, i + x.i);}
     17     Vir operator - (Vir &x) { return Vir(r - x.r, i - x.i);}
     18     Vir operator * (Vir &x) { return Vir(r * x.r - i * x.i, r * x.i + i * x.r);}
     19 } rev[N << 1], v1[N << 1], v2[N << 1];
     20 
     21 const int M = 22;
     22 int ep[M];
     23 double base[M], cosb[M], sinb[M];
     24 
     25 void PRE() {
     26     ep[0] = 1;
     27     for (int i = 1; i < M; i++) ep[i] = ep[i - 1] << 1;
     28     for (int i = 0; i < M - 1; i++) base[i] = 2 * PI / ep[i + 1];
     29     for (int i = 0; i < M - 1; i++) sinb[i] = sin(base[i]), cosb[i] = cos(base[i]);
     30 }
     31 
     32 inline int revbit(int x, int l) {
     33     int ret = 0;
     34     while (l--) ret <<= 1, ret |= x & 1, x >>= 1;
     35     return ret;
     36 }
     37 
     38 inline void reverse(Vir *a, int len) {
     39     int bits = (int) ceil(log((double) len) / log(2.0));
     40     for (int i = 0; i < len; i++) rev[revbit(i, bits)] = a[i];
     41     for (int i = 0; i < len; i++) a[i] = rev[i];
     42 }
     43 
     44 const Vir unit = Vir(1.0, 0.0);
     45 
     46 void fft(Vir *a, int len, bool idft) {
     47     Vir u, t;
     48     int bits = (int) ceil(log((double) len) / log(2.0));
     49     reverse(a, len);
     50     for (int i = 0; i < bits; i++) {
     51         Vir wi, w;
     52         wi.r = cosb[i];
     53         wi.i = idft ? -sinb[i] : sinb[i];
     54         for (int k = 0; k < len; k+= ep[i + 1]) {
     55             w = unit;
     56             for (int j = 0; j < ep[i]; j++) {
     57                 t = w * a[k + j + ep[i]];
     58                 u = a[k + j];
     59                 a[k + j] = u + t;
     60                 a[k + j + ep[i]] = u - t;
     61                 w = w * wi;
     62             }
     63         }
     64     }
     65     if (idft) for (int i = 0; i < len; i++) a[i].r /= len;
     66 }
     67 
     68 void cal(Vir *a, Vir *b, int len) {
     69     fft(a, len, 0);
     70     fft(b, len, 0);
     71     for (int i = 0; i < len; i++) a[i] = a[i] * b[i];
     72     fft(a, len, 1);
     73 }
     74 
     75 int rec[N];
     76 typedef long long LL;
     77 LL cnt[N << 1];
     78 
     79 bool test(int a, int b, int c) {
     80     if (a + b <= c) return false;
     81     if (a + c <= b) return false;
     82     if (b + c <= a) return false;
     83     return true;
     84 }
     85 
     86 double BF(int n) {
     87     int cnt = 0;
     88     for (int i = 0; i < n; i++) {
     89         for (int j = i + 1; j < n; j++) {
     90             for (int k = j + 1; k < n; k++) {
     91                 cnt += test(rec[i], rec[j], rec[k]);
     92             }
     93         }
     94     }
     95     return 6.0 * cnt / (n * (n - 1) * (n - 2));
     96 }
     97 
     98 int main() {
     99     int n, x, T;
    100     PRE();
    101     cin >> T;
    102     while (T-- && cin >> n) {
    103         memset(v1, 0, sizeof(v1));
    104         memset(v2, 0, sizeof(v2));
    105         int mx = 0;
    106         for (int i = 0; i < n; i++) {
    107             scanf("%d", &x);
    108             rec[i] = x;
    109             v1[x].r += 1.0;
    110             v2[x].r += 1.0;
    111             mx = max(x, mx);
    112         }
    113         mx++;
    114         int len = 0;
    115         while (ep[len] < mx) len++;
    116         len = ep[len + 1];
    117         cal(v1, v2, len);
    118         LL tt = (LL) n * (n - 1) * (n - 2) / 6, ans = tt;
    119         for (int i = 0; i < len; i++) cnt[i] = (LL) floor(v1[i].r + 0.5);
    120         for (int i = 0; i < n; i++) cnt[rec[i] << 1]--;
    121         for (int i = 0; i < len; i++) {
    122             cnt[i] >>= 1;
    123             cnt[i] += cnt[i - 1];
    124         }
    125         for (int i = 0; i < n; i++) ans -= cnt[rec[i]];
    126         printf("%.7f
    ", ans * 1.0 / tt);
    127     }
    128     return 0;
    129 }
    View Code

     UPD:

     Problem - 4605

      题意是,给定一棵点上带权的树,要求求出从根出发到达给定结点按照要求求出的概率值。

      这题可以有很多做法,比较容易想到的可能是树链剖分,不过这题用树链剖分的话估计vector之类的stl会导致超时。这题有一个简单的方法,就是在遍历树的时候同时处理query,也就是离线处理。遍历的过程中,记录两样东西,一个是从根结点到当前结点有哪些权值,另一个是从根结点到当前结点需要向右走的结点有哪些权值。

      遍历到当前结点的时候,求出有多少个已存的权值比当前权值小和大,还有多少个已存的向右走的结点的权值比当前权值小。

      加了个栈挂,1y~

    代码如下:

      1 #pragma comment(linker, "/STACK:102400000,102400000")
      2 
      3 #include <cstdio>
      4 #include <iostream>
      5 #include <algorithm>
      6 #include <cstring>
      7 #include <map>
      8 
      9 using namespace std;
     10 
     11 const int N = 111111;
     12 struct Node {
     13     int w, c[2];
     14 } node[N];
     15 map<int, int> id;
     16 int rx[N];
     17 
     18 inline int lowbit(int x) { return x & (-x);}
     19 struct BIT {
     20     int s[N << 1], sz, tt;
     21     void init(int size) { memset(s, 0, sizeof(s)); sz = size + 10, tt = 0;}
     22     void inc(int x) { tt++, x += 10; for ( ; x < N; x += lowbit(x)) s[x]++;}
     23     void dec(int x) { tt--, x += 10; for ( ; x < N; x += lowbit(x)) s[x]--;}
     24     int sum(int x) {
     25         int ret = 0;
     26         for (x += 10; x > 0; x -= lowbit(x)) ret += s[x];
     27         return ret;
     28     }
     29     int sum(int l, int r) { return sum(r) - sum(l - 1);}
     30 } all, rt;
     31 
     32 struct Query {
     33     int x, nx, id;
     34     Query() {}
     35     Query(int x, int nx, int id) : x(x), nx(nx), id(id) {}
     36 } qry[N];
     37 int qs[N], qc;
     38 int q1[N], q2[N], cnt[N];
     39 
     40 void init() {
     41     memset(qs, -1, sizeof(qs));
     42     qc = 0;
     43 }
     44 
     45 void addqry(int v, int x, int id) {
     46     qry[qc] = Query(x, qs[v], id);
     47     qs[v] = qc++;
     48 }
     49 
     50 void dfs(int x) {
     51     int wt = id[node[x].w], t;
     52     for (t = qs[x]; ~t; t = qry[t].nx) {
     53         Query &q = qry[t];
     54         if (cnt[id[q.x]]) {
     55             q1[q.id] = -1;
     56             continue;
     57         }
     58         int w = id[q.x];
     59         int lwr = all.sum(w - 1), upr = all.tt - lwr - cnt[w];
     60         int lw = rt.sum(w - 1);
     61         q1[q.id] = lw;
     62         q2[q.id] = upr + lwr * 3;
     63     }
     64     all.inc(wt);
     65     cnt[wt]++;
     66     if (~node[x].c[0]) dfs(node[x].c[0]);
     67     rt.inc(wt);
     68     if (~node[x].c[1]) dfs(node[x].c[1]);
     69     rt.dec(wt);
     70     all.dec(wt);
     71     cnt[wt]--;
     72 }
     73 
     74 bool nrt[N];
     75 
     76 int main() {
     77 //    freopen("in", "r", stdin);
     78     int T, n, m, q;
     79     int x, y, f;
     80     scanf("%d", &T);
     81     while (T-- && ~scanf("%d", &n)) {
     82         id.clear();
     83         for (int i = 1; i <= n; i++) {
     84             scanf("%d", &node[i].w);
     85             rx[i - 1] = node[i].w;
     86             node[i].c[0] = node[i].c[1] = -1;
     87         }
     88         memset(nrt, 0, sizeof(nrt));
     89         scanf("%d", &m);
     90         while (m--) {
     91             scanf("%d%d%d", &f, &x, &y);
     92             node[f].c[0] = x, node[f].c[1] = y;
     93             nrt[x] = nrt[y] = true;
     94         }
     95         init();
     96         scanf("%d", &q);
     97         for (int i = 0; i < q; i++) {
     98             scanf("%d%d", &x, &y);
     99             rx[i + n] = y;
    100             addqry(x, y, i);
    101         }
    102         sort(rx, rx + n + q);
    103         m = (int) (unique(rx, rx + n + q) - rx);
    104         all.init(m);
    105         rt.init(m);
    106         for (int i = 0; i < m; i++) id[rx[i]] = i;
    107         int rt = -1;
    108         for (int i = 1; i <= n; i++) if (!nrt[i]) rt = i;
    109         if (rt == -1) {
    110             puts("WTF?!");
    111             while (1) ;
    112         }
    113         dfs(1);
    114         for (int i = 0; i < q; i++) {
    115             if (q1[i] == -1) puts("0");
    116             else printf("%d %d
    ", q1[i], q2[i]);
    117         }
    118     }
    119     return 0;
    120 }
    View Code

     UPD:

      改成非递归的:

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <algorithm>
      4 #include <cstring>
      5 #include <map>
      6 
      7 using namespace std;
      8 
      9 const int N = 111111;
     10 struct Node {
     11     int w, c[2];
     12 } node[N];
     13 map<int, int> id;
     14 int rx[N];
     15 
     16 inline int lowbit(int x) { return x & (-x);}
     17 struct BIT {
     18     int s[N << 1], sz, tt;
     19     void init(int size) { memset(s, 0, sizeof(s)); sz = size + 10, tt = 0;}
     20     void inc(int x) { tt++, x += 10; for ( ; x < N; x += lowbit(x)) s[x]++;}
     21     void dec(int x) { tt--, x += 10; for ( ; x < N; x += lowbit(x)) s[x]--;}
     22     int sum(int x) {
     23         int ret = 0;
     24         for (x += 10; x > 0; x -= lowbit(x)) ret += s[x];
     25         return ret;
     26     }
     27     int sum(int l, int r) { return sum(r) - sum(l - 1);}
     28 } all, rt;
     29 
     30 struct Query {
     31     int x, nx, id;
     32     Query() {}
     33     Query(int x, int nx, int id) : x(x), nx(nx), id(id) {}
     34 } qry[N];
     35 int qs[N], qc;
     36 int q1[N], q2[N], cnt[N];
     37 
     38 void init() {
     39     memset(qs, -1, sizeof(qs));
     40     qc = 0;
     41 }
     42 
     43 void addqry(int v, int x, int id) {
     44     qry[qc] = Query(x, qs[v], id);
     45     qs[v] = qc++;
     46 }
     47 
     48 int sv[N], top;
     49 int vis[N];
     50 void dfs(int x) {
     51     top = -1;
     52     sv[++top] = x;
     53     vis[top] = 0;
     54     while (top >= 0) {
     55         x = sv[top];
     56         int st = vis[top--], wt = id[node[x].w], t;
     57         if (st == 0) {
     58             for (t = qs[x]; ~t; t = qry[t].nx) {
     59                 Query &q = qry[t];
     60                 if (cnt[id[q.x]]) {
     61                     q1[q.id] = -1;
     62                     continue;
     63                 }
     64                 int w = id[q.x];
     65                 int lwr = all.sum(w - 1), upr = all.tt - lwr - cnt[w];
     66                 int lw = rt.sum(w - 1);
     67                 q1[q.id] = lw;
     68                 q2[q.id] = upr + lwr * 3;
     69             }
     70             all.inc(wt);
     71             cnt[wt]++;
     72             sv[++top] = x;
     73             vis[top] = 1;
     74             if (~node[x].c[0]) sv[++top] = node[x].c[0], vis[top] = 0;
     75         } else if (st == 1) {
     76             rt.inc(wt);
     77             sv[++top] = x;
     78             vis[top] = 2;
     79             if (~node[x].c[1]) sv[++top] = node[x].c[1], vis[top] = 0;
     80         } else {
     81             rt.dec(wt);
     82             all.dec(wt);
     83             cnt[wt]--;
     84         }
     85     }
     86 }
     87 
     88 bool nrt[N];
     89 
     90 int main() {
     91 //    freopen("in", "r", stdin);
     92     int T, n, m, q;
     93     int x, y, f;
     94     scanf("%d", &T);
     95     while (T-- && ~scanf("%d", &n)) {
     96         id.clear();
     97         for (int i = 1; i <= n; i++) {
     98             scanf("%d", &node[i].w);
     99             rx[i - 1] = node[i].w;
    100             node[i].c[0] = node[i].c[1] = -1;
    101         }
    102         memset(nrt, 0, sizeof(nrt));
    103         scanf("%d", &m);
    104         while (m--) {
    105             scanf("%d%d%d", &f, &x, &y);
    106             node[f].c[0] = x, node[f].c[1] = y;
    107             nrt[x] = nrt[y] = true;
    108         }
    109         init();
    110         scanf("%d", &q);
    111         for (int i = 0; i < q; i++) {
    112             scanf("%d%d", &x, &y);
    113             rx[i + n] = y;
    114             addqry(x, y, i);
    115         }
    116         sort(rx, rx + n + q);
    117         m = (int) (unique(rx, rx + n + q) - rx);
    118         all.init(m);
    119         rt.init(m);
    120         for (int i = 0; i < m; i++) id[rx[i]] = i;
    121         int rt = -1;
    122         for (int i = 1; i <= n; i++) if (!nrt[i]) rt = i;
    123         if (rt == -1) {
    124             puts("WTF?!");
    125             while (1) ;
    126         }
    127         dfs(1);
    128         for (int i = 0; i < q; i++) {
    129             if (q1[i] == -1) puts("0");
    130             else printf("%d %d
    ", q1[i], q2[i]);
    131         }
    132     }
    133     return 0;
    134 }
    View Code

     UPD:

      贴一下队友ly的1008(hdu 4607)的代码:

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <map>
     6 #include <queue>
     7 #include <stack>
     8 #include <set>
     9 
    10 const int N = 1e5+5;
    11 const int inf = 1<<28;
    12 using namespace std;
    13 int n,m;
    14 int tot,pre[N];
    15 struct edge{
    16     int v,next;
    17 }e[N<<1];
    18 
    19 void init(){
    20     tot=0;
    21     memset(pre,-1,sizeof(pre));
    22 }
    23 
    24 void add(int u,int v){
    25     edge E={v,pre[u]};
    26     e[tot]=E,pre[u]=tot++;
    27 }
    28 
    29 void input(){
    30     int u,v;
    31     scanf("%d%d",&n,&m);
    32     for(int i=1;i<n;i++){
    33         scanf("%d%d",&u,&v);
    34         add(u,v),add(v,u);
    35     }
    36 }
    37 
    38 int dis[N],vis[N];
    39 int bfs(int s,int &t){
    40     queue<int> q;
    41     memset(vis,0,sizeof(vis));
    42     dis[s]=0,vis[s]=1,t=s;
    43     q.push(s);
    44     int res=0;
    45     while(!q.empty()){
    46         int u=q.front();
    47         q.pop();
    48         if(res<dis[u]){
    49             res=dis[u];
    50             t=u;
    51         }
    52         for(int i=pre[u];i!=-1;i=e[i].next){
    53             int v=e[i].v;
    54             if(!vis[v]){
    55                 dis[v]=dis[u]+1;
    56                 vis[v]=1;
    57                 q.push(v);
    58             }
    59         }
    60     }
    61     return res+1;
    62 }
    63 
    64 void query(){
    65     int k,u,v;
    66     int tmp=bfs(1,v);
    67     tmp=bfs(v,u);
    68     while(m--){
    69         scanf("%d",&k);
    70         if(k<=tmp) printf("%d
    ",k-1);
    71         else printf("%d
    ",tmp-1+(k-tmp)*2);
    72     }
    73 }
    74 
    75 int main(){
    76     int t;
    77     scanf("%d",&t);
    78     while(t--){
    79         init();
    80         input();
    81         query();
    82     }
    83     return 0;
    84 }
    View Code

    ——written by Lyon

  • 相关阅读:
    走向灵活软件之路——面向对象的六大原则
    StartUML破解
    非常实用的Android Studio快捷键
    Android Studio更新失败
    《Effect Java》学习笔记1———创建和销毁对象
    使用spring单元调试出错initializationError
    Spring注入的不同方式
    DNS域名解析的过程
    浏览器的缓存机制
    Http建立连接的方式
  • 原文地址:https://www.cnblogs.com/LyonLys/p/2013_07_23_Lyon.html
Copyright © 2011-2022 走看看