UVA11732 "strcmp()" Anyone?【左兒子右兄弟Trie】

LINK1c++

LINK2git


題目大意

給你一些字符串,並定義了一個函數(具體見題面)函數

問你把任意兩個字符串放到函數裏面獲得的值的和是多少spa

思路

該怎麼統計答案呢?.net

每次考慮當前插入的串和全部已經插入過的串一塊兒統計答案指針

而後考慮一下怎麼統計,假設當前深度是depcode

而且如今是u,即將向v移動指針字符串

那麼怎麼同幾當前這一層的答案呢?get

全部在v的子樹中的節點顯然是不能在這一層統計答案的input

因此就考慮統計和全部不在同一個子樹的答案

具體實現很簡單,讀者本身思考吧


注意在每一次走到字符串的末尾的時候須要特判

和他相同或者包含它的字符串會比較更多的次數,因此不能直接中止也要繼續移動指針,能夠強行讓最後一個位置變成奇怪字符

而後這題須要左兄弟右兒子的trie

具體實現參考代碼(其實並不麻煩,別怕)


//Author: dream_maker
#include<bits/stdc++.h>
using namespace std;
//----------------------------------------------
typedef pair<int, int> pi;
typedef long long ll;
typedef double db;
#define fi first
#define se second
#define fu(a, b, c) for (int a = b; a <= c; ++a)
#define fd(a, b, c) for (int a = b; a >= c; --a)
#define fv(a, b) for (int a = 0; a < (signed)b.size(); ++a)
const int INF_of_int = 1e9;
const ll INF_of_ll = 1e18;
template <typename T>
void Read(T &x) {
  bool w = 1;x = 0;
  char c = getchar();
  while (!isdigit(c) && c != '-') c = getchar();
  if (c == '-') w = 0, c = getchar();
  while (isdigit(c)) {
    x = (x<<1) + (x<<3) + c -'0';
    c = getchar();
  }
  if (!w) x = -x;
}
template <typename T>
void Write(T x) {
  if (x < 0) {
    putchar('-');
    x = -x;
  }
  if (x > 9) Write(x / 10);
  putchar(x % 10 + '0');
}
//----------------------------------------------
const int N = 6e6 + 10;
struct Node {
  char ch;
  int val;
  Node *son, *bro;
  Node(char ch = 0, int val = 0, Node *son = NULL, Node *bro = NULL):ch(ch), val(val), son(son), bro(bro) {}
} *rt, pool[N], *cur = pool;
ll ans;
void insert(char *s) {
  int len = strlen(s);
  s[len] = '#';
  Node *u = rt, *v;
  fu(i, 0, len) {
    v = u->son;
    for (; v; v = v->bro)
      if (v->ch == s[i]) break;
    if (!v) {
      v = new (cur++) Node(s[i], 0, NULL, u->son);
      u->son = v;
    }
    ans += 1ll * (u->val - v->val) * (2 * i + 1);
    if (i == len) {
      ans += 1ll * v->val * (2 * len + 2);
      ++v->val;
    }
    ++u->val;
    u = v;
  }
}
char s[N];
int main() {
#ifdef dream_maker
  freopen("input.txt", "r", stdin);
#endif
  int n, tot = 0;
  while (1) {
    Read(n);
    if (!n) break;
    cur = pool;
    rt = new (cur++) Node();
    ans = 0;
    fu(i, 1, n) {
      scanf("%s", s);
      insert(s);
    }
    printf("Case %d: %lld\n", ++tot, ans);
  }
  return 0;
}
相關文章
相關標籤/搜索