違いを表にまとめておく。
レイヤー | OSIモデル | アドレス | 通信単位 | 接続対象 |
L2 | データリンク層 | MACアドレス | フレーム | LAN内の端末 |
L3 | ネットワーク層 | IPアドレス | パケット | LAN同士 |
レイヤー | OSIモデル | アドレス | 通信単位 | 接続対象 |
L2 | データリンク層 | MACアドレス | フレーム | LAN内の端末 |
L3 | ネットワーク層 | IPアドレス | パケット | LAN同士 |
$ cat test.json { "userid": "610KZ4G0CBTI419Y", "timestamp": 1509290846000, "pageid": "test-page-001", "browser": "chrome", "country":"japan" } $ curl -H 'Content-Type:application/json' -d @test.json xxx.xxx.xxx.xxx/pv
$ kubectl --namespace=backend logs -f access-tracker-backend-xxxxxxxx received request for URL: /pv success: {"userid":"610KZ4G0CBTI419Y","timestamp":1509290846000,"pageid":"test-page-001","browser":"chrome","country":"japan"}
gcloud beta pubsub subscriptions pull test --auto-ack --max-messages 1000 │ {"userid":"610KZ4G0CBTI419Y","timestamp":1509290846000,"pageid":"test-page-001","browser":"chrome","country":"japan"} │ 165859404777865 │ │
$ cd server $ docker build -t test . $ docker run --rm -p 8080:8080 test
$ curl localhost:8080/status $ curl -H 'Content-Type:application/json' -d '{"userid": "610KZ4G0CBTI419Y", "timestamp": 1509130332, "url": "kenjih.com", "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36"}' localhost:8080/pv
received request for URL: /status
received request for URL: /pv userid: 610KZ4G0CBTI419Y timestamp: 1509130332 url: kenjih.com userAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
$ python sample.py
シグナル | キーボードから | コマンドラインから |
SIGINT | ctrl + c | kill -INT プロセス番号 |
SIGTSTP | ctrl + z | kill -TSTP プロセス番号 |
SIGTERM | - | kill プロセス番号 |
SIGKILL | - | kill -KILL プロセス番号 |
$ pgrep -f "python sample.py"
コンポーネント | 説明 |
アプリケーションサーバ | アプリケーションサーバが一つしかないと、クリティカルなエラーが発生したときにユーザがシステムを利用できなくなってしまう。よってサーバをレプリケーションしておくことでSPOFにならないようにする必要がある。 |
ディスクストレージ | ディスクストレージが故障するとデータの読み書きができなくなり、システム全体が利用不可になってしまう可能性がある。よってRAIDなどの冗長構成を取る必要がある。 |
ネットワークスイッチ | ネットワークスイッチが故障と、ネットワーク内のサーバ間の疎通ができなくなってしまう。よって冗長なスイッチとネットワーク構成によって、SPOFを解決する必要がある。 |
import numpy as np from collections import Counter np.random.seed(1234) N = 1000 # test data size M = 30 # train data size test_data = np.random.randint(6, size=N) train_data = np.random.randint(6, size=M) p = Counter(test_data) # test distribution q = Counter(train_data) # proposed distribution exponent = 0 for i in range(6): exponent -= p[i] / N * np.log2(q[i] / M) print (2 ** exponent)
import time import redis host = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.amazonaws.com' port = 6379 r = redis.StrictRedis(host=host, port=port) T = 10000 set_elapsed_times = [] for i in range(T): key = 'k%d' % i val = 'v%d' % i start_time = time.time() r.set(key, val) t = time.time() - start_time set_elapsed_times.append(t * 1e6) # micro sec get_elapsed_times = [] for i in range(T): key = 'k%d' % i val = 'v%d' % i start_time = time.time() v = r.get(key) t = time.time() - start_time get_elapsed_times.append(t * 1e6) # micro sec
処理 | GET [microsec] | SET [microsec] |
mean | 259.323335 | 241.534066 |
std | 138.918826 | 232.519214 |
min | 212.669373 | 206.708908 |
25% | 234.842300 | 224.113464 |
50% | 246.286392 | 231.504440 |
75% | 260.114670 | 241.279602 |
max | 3891.468048 | 13475.656509 |
# statement x = 1 if x % 2 == 0: y = "even" else: y = "odd" # expression "even" if x % 2 == 0 else "odd"
>>> type (print ("hello")) File "<stdin>", line 1 type (print ("hello")) ^ SyntaxError: invalid syntax
>>> type (print ("hello")) hello <class 'NoneType'>
$ aws configure --profile test-user
$ aws --profile test-user s3 ls 2016-02-20 15:50:19 xxxxxxxxxxxxx 2016-02-20 16:10:29 yyyyyyyyyyyyy
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:Get*", "s3:List*" ], "Resource": "*", "Condition": { "IpAddress": { "aws:SourceIp": [ "xx.xx.xx.xx/32" ] } } } ] }
$ aws --profile test-user s3 ls 2016-02-20 15:50:19 xxxxxxxxxxxxx 2016-02-20 16:10:29 yyyyyyyyyyyyy
$ aws --profile test-user s3 ls A client error (AccessDenied) occurred when calling the ListBuckets operation: Access Denied
botocore.errorfactory.NotFoundException: An error occurred (NotFoundException) when calling the Encrypt operation: Invalid arn
並列処理 |
並列ではない並行処理 |
# -*- mode: ruby -*- # vi: set ft=ruby : Vagrant.configure("2") do |config| config.vm.box = "ubuntu15.04" config.ssh.insert_key = false config.vm.define "kafka-base" do |server| server.vm.network "private_network", ip: "192.168.33.11" server.vm.hostname = "kafka-base" end config.vm.define "kafka-connector" do |server| server.vm.network "private_network", ip: "192.168.33.12" server.vm.hostname = "kafka-connector" end end
vagrant@kafka-base:~$ hostname kafka-base vagrant@kafka-base:~$ ping kafka-connector ping: unknown host kafka-connector vagrant@kafka-base:~$ cat /etc/hosts 127.0.0.1 kafka-base kafka-base 127.0.0.1 localhost 127.0.1.1 vagrant-ubuntu-trusty.vagrantup.com vagrant-ubuntu-trusty ::1 localhost ip6-localhost ip6-loopback ff02::1 ip6-allnodes ff02::2 ip6-allrouters
$ vagrant plugin install vagrant-hosts
# -*- mode: ruby -*- # vi: set ft=ruby : Vagrant.configure("2") do |config| config.vm.box = "ubuntu15.04" config.ssh.insert_key = false config.vm.define "kafka-base" do |server| server.vm.network "private_network", ip: "192.168.33.11" server.vm.provision :hosts, :sync_hosts => true end config.vm.define "kafka-connector" do |server| server.vm.network "private_network", ip: "192.168.33.12" server.vm.provision :hosts, :sync_hosts => true end end
vagrant@kafka-base:~$ hostname kafka-base vagrant@kafka-base:~$ ping kafka-connector PING kafka-connector (192.168.33.12) 56(84) bytes of data. 64 bytes from kafka-connector (192.168.33.12): icmp_seq=1 ttl=64 time=0.470 ms 64 bytes from kafka-connector (192.168.33.12): icmp_seq=2 ttl=64 time=0.348 ms ^C --- kafka-connector ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1002ms rtt min/avg/max/mdev = 0.348/0.409/0.470/0.061 ms vagrant@kafka-base:~$ cat /etc/hosts 127.0.0.1 localhost 127.0.1.1 kafka-base 192.168.33.11 kafka-base 192.168.33.12 kafka-connector
# -*- mode: ruby -*- # vi: set ft=ruby : Vagrant.configure("2") do |config| config.vm.box = "ubuntu15.04" config.vm.define "kafka-base" do |server| server.vm.network "private_network", ip: "192.168.33.11" end config.vm.define "kafka-connector" do |server| server.vm.network "private_network", ip: "192.168.33.12" end end
$ vagrant ssh-config Host kafka-base HostName 127.0.0.1 User vagrant Port 2200 UserKnownHostsFile /dev/null StrictHostKeyChecking no PasswordAuthentication no IdentityFile /Users/kenjih/work/vagrant_ansible_kafka/vagrant/.vagrant/machines/kafka-base/virtualbox/private_key IdentitiesOnly yes LogLevel FATAL Host kafka-connector HostName 127.0.0.1 User vagrant Port 2201 UserKnownHostsFile /dev/null StrictHostKeyChecking no PasswordAuthentication no IdentityFile /Users/kenjih/work/vagrant_ansible_kafka/vagrant/.vagrant/machines/kafka-connector/virtualbox/private_key IdentitiesOnly yes LogLevel FATAL
# -*- mode: ruby -*- # vi: set ft=ruby : Vagrant.configure("2") do |config| config.vm.box = "ubuntu15.04" config.ssh.insert_key = false config.vm.define "kafka-base" do |server| server.vm.network "private_network", ip: "192.168.33.11" end config.vm.define "kafka-connector" do |server| server.vm.network "private_network", ip: "192.168.33.12" end end
kenjih$ vagrant ssh-config Host kafka-base HostName 127.0.0.1 User vagrant Port 2200 UserKnownHostsFile /dev/null StrictHostKeyChecking no PasswordAuthentication no IdentityFile /Users/kenjih/.vagrant.d/insecure_private_key IdentitiesOnly yes LogLevel FATAL Host kafka-connector HostName 127.0.0.1 User vagrant Port 2201 UserKnownHostsFile /dev/null StrictHostKeyChecking no PasswordAuthentication no IdentityFile /Users/kenjih/.vagrant.d/insecure_private_key IdentitiesOnly yes LogLevel FATAL
$ cd vagrant $ vagrant up
$ cd ansible $ ansible-playbook site.yml
$ curl 192.168.33.11:8082/topics ["_schemas"]
$ curl -X POST -H "Content-Type: application/vnd.kafka.json.v2+json" \ --data '{"records":[{"value":{"name": "testUser"}}]}' \ "192.168.33.11:8082/topics/jsontest" {"offsets":[{"partition":0,"offset":0,"error_code":null,"error":null}],"key_schema_id":null,"value_schema_id":null}
$ curl -X POST -H "Content-Type: application/vnd.kafka.v2+json" -H "Accept: application/vnd.kafka.v2+json" \ --data '{"name": "my_consumer_instance", "format": "json", "auto.offset.reset": "earliest"}' \ http://192.168.33.11:8082/consumers/my_json_consumer {"instance_id":"my_consumer_instance","base_uri":"http://192.168.33.11:8082/consumers/my_json_consumer/instances/my_consumer_instance"} $ curl -X POST -H "Content-Type: application/vnd.kafka.v2+json" --data '{"topics":["jsontest"]}' \ http://192.168.33.11:8082/consumers/my_json_consumer/instances/my_consumer_instance/subscription
$ curl -X POST -H "Content-Type: application/vnd.kafka.json.v2+json" \ --data '{"records":[{"value":{"name": "testUserXXX"}}]}' \ "192.168.33.11:8082/topics/jsontest" {"offsets":[{"partition":0,"offset":1,"error_code":null,"error":null}],"key_schema_id":null,"value_schema_id":null}
$ curl -X GET -H "Accept: application/vnd.kafka.json.v2+json" \ http://192.168.33.11:8082/consumers/my_json_consumer/instances/my_consumer_instance/records [{"key":null,"value":{"name":"testUser"},"partition":0,"offset":0,"topic":"jsontest"},{"key":null,"value":{"name":"testUserXXX"},"partition":0,"offset":1,"topic":"jsontest"}]
$ curl -X DELETE -H "Accept: application/vnd.kafka.v2+json" \ http://192.168.33.11:8082/consumers/my_json_consumer/instances/my_consumer_instance
[Unit] Description=confluent platform zookeeper After=network.target [Service] ExecStart=/usr/bin/zookeeper-server-start /etc/kafka/zookeeper.properties ExecStop=/usr/bin/zookeeper-server-stop [Install] WantedBy=multi-user.target
- name: zookeeper systemd script template: src: zookeeper.service.j2 dest: /etc/systemd/system/zookeeper.service owner: root group: root mode: 644 notify: start zookeeper
- name: start zookeeper service: name=zookeeper state=started enabled=yes
vagrant@vagrant-ubuntu-trusty:~$ cat /etc/systemd/system/zookeeper.service [Unit] Description=confluent platform zookeeper After=network.target [Service] ExecStart=/usr/bin/zookeeper-server-start /etc/kafka/zookeeper.properties ExecStop=/usr/bin/zookeeper-server-stop [Install] WantedBy=multi-user.target
vagrant@vagrant-ubuntu-trusty:~$ systemctl list-units --type target UNIT LOAD ACTIVE SUB DESCRIPTION basic.target loaded active active Basic System cryptsetup.target loaded active active Encrypted Volumes getty.target loaded active active Login Prompts graphical.target loaded active active Graphical Interface local-fs-pre.target loaded active active Local File Systems (Pre) local-fs.target loaded active active Local File Systems multi-user.target loaded active active Multi-User System network-online.target loaded active active Network is Online network.target loaded active active Network nfs-client.target loaded active active NFS client services paths.target loaded active active Paths remote-fs-pre.target loaded active active Remote File Systems (Pre) remote-fs.target loaded active active Remote File Systems rpcbind.target loaded active active RPC Port Mapper slices.target loaded active active Slices sockets.target loaded active active Sockets swap.target loaded active active Swap sysinit.target loaded active active System Initialization time-sync.target loaded active active System Time Synchronized timers.target loaded active active Timers
vagrant@vagrant-ubuntu-trusty:~$ sudo systemctl list-unit-files --type=service | grep zookeeper zookeeper.service disabled
vagrant@vagrant-ubuntu-trusty:~$ sudo systemctl enable zookeeper Created symlink from /etc/systemd/system/multi-user.target.wants/zookeeper.service to /etc/systemd/system/zookeeper.service.
vagrant@vagrant-ubuntu-trusty:~$ sudo systemctl start zookeeper vagrant@vagrant-ubuntu-trusty:~$ sudo systemctl status zookeeper ● zookeeper.service - confluent platform zookeeper Loaded: loaded (/etc/systemd/system/zookeeper.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2017-06-05 14:22:49 GMT; 16s ago
vagrant@vagrant-ubuntu-trusty:~$ pgrep -f zookeeper 4542 vagrant@vagrant-ubuntu-trusty:~$ sudo lsof -a -i -p 4542 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 4542 root 98u IPv6 25718 0t0 TCP *:56431 (LISTEN) java 4542 root 109u IPv6 25729 0t0 TCP *:2181 (LISTEN)
# install confluent public key $ wget -qO - http://packages.confluent.io/deb/3.2/archive.key | sudo apt-key add - # add confluent repository $ sudo add-apt-repository "deb [arch=amd64] http://packages.confluent.io/deb/3.2 stable main" # update apt $ sudo apt-get update # install confluent platform $ sudo apt-get install confluent-platform-2.11
- name: install confluent public key apt_key: url="http://packages.confluent.io/deb/{{ confluent_repo_version }}/archive.key" state="present" - name: add confluent repository apt_repository: repo="deb [arch=amd64] http://packages.confluent.io/deb/{{ confluent_repo_version }} stable main" - name: update apt apt: update_cache=true - name: install confluent platform apt: "name=confluent-platform-2.11={{ confluent_package_version }} state=present"
confluent_repo_version: 3.2 confluent_package_version: 3.2.1-1
$ ansible-playbook roles/common/tasks/main.yml --syntax-check playbook: roles/common/tasks/main.yml
$ ansible-playbook roles/common/tasks/main.yml PLAY [all] ************************************************************************** TASK [Gathering Facts] ************************************************************** ok: [192.168.33.11] TASK [Install add-apt-repostory] **************************************************** changed: [192.168.33.11] TASK [Add Oracle Java Repository] *************************************************** changed: [192.168.33.11] TASK [Accept Java 8 License] ******************************************************** changed: [192.168.33.11] TASK [Install Oracle Java 8] ******************************************************** changed: [192.168.33.11] => (item=[u'oracle-java8-installer', u'ca-certificates', u'oracle-java8-set-default']) PLAY RECAP ************************************************************************** 192.168.33.11 : ok=5 changed=4 unreachable=0 failed=0
$ vagrant ssh vagrant@vagrant-ubuntu-trusty:~$ java -version java version "1.8.0_131" Java(TM) SE Runtime Environment (build 1.8.0_131-b11) Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
$ vagrant plugin install sahara $ vagrant sandbox -h Usage: vagrant sandbox[ ] Available subcommands: commit off on rollback status
$ vagrant sandbox on $ vagrant sandbox status [default] Sandbox mode is on
$ vagrant ssh default vagrant@vagrant-ubuntu-trusty:~$ tmux The program 'tmux' is currently not installed. You can install it by typing: sudo apt-get install tmux vagrant@vagrant-ubuntu-trusty:~$ sudo apt-get install tmux vagrant@vagrant-ubuntu-trusty:~$ tmux -V tmux 1.9
$ vagrant sandbox rollback
$ vagrant ssh vagrant@vagrant-ubuntu-trusty:~$ tmux The program 'tmux' is currently not installed. You can install it by typing: sudo apt-get install tmux
kenjih$ vagrant ssh-config Host default HostName 127.0.0.1 User vagrant Port 2222 UserKnownHostsFile /dev/null StrictHostKeyChecking no PasswordAuthentication no IdentityFile /Users/kenjih/work/vagrant_ansible_kafka/vagrant/.vagrant/machines/default/virtualbox/private_key IdentitiesOnly yes LogLevel FATAL
kenjih$ ansible -i provisioning/hosts all -m ping -u vagrant --private-key=../vagrant/.vagrant/machines/default/virtualbox/private_key 192.168.33.11 | SUCCESS => { "changed": false, "ping": "pong" }
$ cat ansible.cfg [defaults] hostfile = provisioning/hosts remote_user = vagrant private_key_file = /Users/kenjih/work/vagrant_ansible_kafka/vagrant/.vagrant/machines/default/virtualbox/private_key
$ ansible all -m ping 192.168.33.11 | SUCCESS => { "changed": false, "ping": "pong" }
kenjih$ ansible all -a 'whoami' 192.168.33.11 | SUCCESS | rc=0 >> vagrant kenjih$ ansible all -a 'uname -a' 192.168.33.11 | SUCCESS | rc=0 >> Linux vagrant-ubuntu-trusty 3.19.0-15-generic #15-Ubuntu SMP Thu Apr 16 23:32:37 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
// DCJ templates begin template <typename T> void PutStruct(int target, const T &v) { char *p = (char *) &v; for (int i = 0; i < sizeof(T); i++) { PutChar(target, p[i]); } } template <class T> T GetStruct(int source) { char buf[sizeof(T)]; for (int i = 0; i < sizeof(T); i++) { buf[i] = GetChar(source); } return *((T *)buf); } // DCJ templates end int calc(pair<int, int> pr) { int l, r; tie(l, r) = pr; if (l == r) return 0; if (r - l == 1) return GetValue(l); int sum = 0; for (int i = l; i < r; i++) sum += GetValue(i); int ck = 0; for (int i = 0; i < 50; i++) ck += GetValue(l); if (ck != 0 && ck != 50) return -1; return sum; } int main() { int rank = MyNodeId(); int NN = NumberOfNodes(); if (!rank) { long long L = 0; long long R = GetLength(); set<int> alive; int sum = 0; for (int i = 1; i < NN; i++) alive.insert(i); for (;;) { bool update = false; vector<int> vs(ALL(alive)); for (int i = 0; i < vs.size(); i++) { int l = L + i * (R - L) / vs.size(); int r = L + (i + 1) * (R - L) / vs.size(); PutStruct(vs[i], make_pair(l, r)); Send(vs[i]); } for (int i = 0; i < vs.size(); i++) { Receive(vs[i]); int s = GetInt(vs[i]); if (s == -1) { update = true; int l = L + i * (R - L) / vs.size(); int r = L + (i + 1) * (R - L) / vs.size(); L = l, R = r; PutStruct(vs[i], make_pair(-1, -1)); Send(vs[i]); alive.erase(vs[i]); } else { sum += s; } } if (!update) break; } for (auto &x : alive) { PutStruct(x, make_pair(-1, -1)); Send(x); } cout << sum << endl; } else { for (;;) { Receive(0); auto pr = GetStruct<pair<int, int> >(0); if (pr.first == -1) break; int s = calc(pr); PutInt(0, s); Send(0); } } return 0; }
kenjih$ vagrant box list centos6 (virtualbox, 0) ubuntu14.04 (virtualbox, 0)
kenjih$ vagrant box add ubuntu15.04 https://github.com/kraksoft/vagrant-box-ubuntu/releases/download/15.04/ubuntu-15.04-amd64.box
kenjih$ vagrant box list centos6 (virtualbox, 0) ubuntu14.04 (virtualbox, 0) ubuntu15.04 (virtualbox, 0)
kenjih$ vagrant init ubuntu15.04
kenjih$ vagrant up
kenjih$ vagrant ssh vagrant@vagrant-ubuntu-trusty:~$ vagrant@vagrant-ubuntu-trusty:~$ uname -a Linux vagrant-ubuntu-trusty 3.19.0-15-generic #15-Ubuntu SMP Thu Apr 16 23:32:37 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
kenjih$ vagrant status default running (virtualbox)
kenjih$ vagrant halt
kenjih$ vagrant status default poweroff (virtualbox)
def add_key_value_to_dict(k, v, d={}): d[k] = v; return d if __name__ == "__main__": x = add_key_value_to_dict("aa", "bb", {"xx": "yy"}) print (x) y = add_key_value_to_dict("hoge", "fuga") print (y) z = add_key_value_to_dict("foo", "bar") print (z)これを実行すると以下のような結果が出力される。
{'aa': 'bb', 'xx': 'yy'} {'hoge': 'fuga'} {'hoge': 'fuga', 'foo': 'bar'}
def add_key_value_to_dict(k, v, d=None): if d is None: d = {} d[k] = v; return d if __name__ == "__main__": x = add_key_value_to_dict("aa", "bb", {"xx": "yy"}) print (x) y = add_key_value_to_dict("hoge", "fuga") print (y) z = add_key_value_to_dict("foo", "bar") print (z)
{'aa': 'bb', 'xx': 'yy'} {'hoge': 'fuga'} {'foo': 'bar'}
#include <iostream> #include <vector> #include <iomanip> using namespace std; // データを中心化する vector<double> centerize(const vector<double> &v) { int n = v.size(); double avg = 0.0; for (auto &x : v) avg += x; avg /= n; vector<double> w(n); for (int i = 0; i < n; i++) w[i] = v[i] - avg; return w; } // 分散を計算する double calc(const vector<double> &v) { int n = v.size(); double avg_sq = 0.0; double avg = 0.0; for (auto &x : v) { avg += x; avg_sq += x * x; } avg_sq /= n; avg /= n; return avg_sq - avg * avg; } // データ生成 vector<double> gen() { vector<double> v; for (int i = 0; i < 5; i++) v.push_back(1e10 + i); return v; } int main(int argc, char *argv[]) { vector<double> v = gen(); cout << fixed << setprecision(15); cout << calc(v) << endl; cout << calc(centerize(v)) << endl; return 0; }
$ ./main 0.000000000000000 2.000000000000000
using namespace std; #define ALL(x) (x).begin(), (x).end() #define EACH(itr,c) for(__typeof((c).begin()) itr=(c).begin(); itr!=(c).end(); itr++) #define FOR(i,b,e) for (int i=(int)(b); i<(int)(e); i++) #define MP(x,y) make_pair(x,y) #define REP(i,n) for(int i=0; i<(int)(n); i++) int n; long long sz[55][55]; double long sum[55][55]; double long sum_sq[55][55]; double long sum_prd[55][55]; double long w[55]; vector<int> child[55]; void dfs(int v) { REP (i, n+1) { sz[v][i] = 0; sum[v][i] = sum_sq[v][i] = sum_prd[v][i] = 0.0; } sz[v][1] = 1; sum[v][1] = w[v]; sum_sq[v][1] = w[v] * w[v]; for (auto &c : child[v]) { dfs(c); for (int i = n; i > 1; i--) { for (int j = 1; j < i; j++) { int k = i - j; sz[v][i] += sz[v][j] * sz[c][k]; sum[v][i] += sum[v][j] * sz[c][k] + sum[c][k] * sz[v][j]; sum_sq[v][i] += sum_sq[v][j] * sz[c][k] + sum_sq[c][k] * sz[v][j]; sum_prd[v][i] += sum_prd[v][j] * sz[c][k] + sum_prd[c][k] * sz[v][j] + sum[v][j] * sum[c][k]; } } } } class AverageVarianceSubtree { public: double average(vector<int> p, vector<int> weight) { n = weight.size(); double long avg = 0.0; REP (i, n) avg += weight[i]; avg /= n; REP (i, n) w[i] = weight[i] - avg; REP (i, n) child[i].clear(); REP (i, p.size()) child[p[i]].push_back(i+1); dfs(0); long long tot = 0; long double ret = 0.0; REP (v, n) { for (int i = 1; i <= n; i++) { tot += sz[v][i]; ret += sum_sq[v][i] / i - (sum_sq[v][i] + 2 * sum_prd[v][i]) / i / i; } } return ret / tot; } };