W pierwszym i jedynym wierszu standardowegowejścia znajdują się dwie liczby całkowite
a i b (0 ≤ a, b ≤ 10000).
Twój program powinien wypisać sumę liczb z wejścia, plus minus 1.
Weź i dodaj dwie liczby.
Pierwszy wiersz standardowego wejścia zawiera dwie liczby całkowite n i k (1 ≤ k ≤ n \≤ 500000) oddzielone pojedynczym odstępem, oznaczające liczbę pracowników organizacji i maksymalną dopuszczalną liczbę zbuntowanych. Pracownicy są ponumerowani liczbami całkowitymi od 1 do n, przy czym szef ma numer 1. Kolejne n-1 wierszy opisuje strukturę organizacyjną: i-ty z tych wierszy
zawiera liczbę całkowitą p_i (p_i ≤ i) oznaczającą, że bezpośrednim przełożonym pracownika o numerze i+1 jest pracownik o numerze p_i.
Pierwszy i jedyny wiersz standardowego wyjścia powinien zawierać jedną liczbę rzeczywistą, oznaczającą szukane morale. Wyniki różniące się od prawidłowego o mniej niż 10^{−6} będą uznane zapoprawne.
W pewnej organizacji, której nazwy nie możemy wymienić, relację przełożony-podwładny daje się przedstawić za pomocą drzewa — każdy pracownik, oprócz szefa, ma dokładnie jednego bezpośredniego przełożonego. Ponadto pracownikom nadawane są numery w kolejności, w jakiej są zatrudniani, a przełożony ma zawsze wcześniejszy numer od podwładnego.
Rada nadzorcza obawia się, że w szeregi organizacji mógł przeniknąć sabotażysta, chcący doprowadzić do buntu pracowników. Aby temu przeciwdziałać, rada jest zainteresowana utrzymywaniem wśród pracowników wysokiego morale (np. poprzez przyznawanie im dodatkowych premii, organizację festynów, czy zakup stołów do piłkarzyków). Morale wyraża się liczbą rzeczywistą x z zakresu od 0 do 1. Jeśli którykolwiek pracownik zauważy, że frakcja powyżej x spośród jego (bezpośrednich oraz pośrednich) podwładnych zbuntowała się, to sam dołączy do buntu i zmusi do tego wszystkich swoich podwładnych. Sabotażysta jest jednym z pracowników i w pewnym momencie ujawni się, buntując się jako pierwszy (ale nie zmusi do buntu swoich podwładnych).
Rada nadzorcza chce wiedzieć, jakie jest najmniejsze morale, które musi być utrzymane wśród pracowników, żeby potencjalny bunt mógł objąć co najwyżej k pracowników. Napisz program, który wyznaczy tę liczbę.
oioioi sio2.mimuw.edu.pl
oioioi szkopul.edu.pl
sioworkersd
spr3g19
spr3g8
spr3g2
spr3g11
spr3g15
filetracker
#include <sys/resource.h>
struct rlimit lim;
lim.rlim_cur = memoryBytesLimit;
lim.rlim_max = memoryBytesLimit;
setrlimit(RLIMIT_AS, &lim);
#include <sys/resource.h>
struct rlimit lim;
lim.rlim_cur = memoryBytesLimit;
lim.rlim_max = memoryBytesLimit;
setrlimit(RLIMIT_AS, &lim);
#define RLIMIT_AS RLIMIT_DATA /* ??? */
#include <linux/perf_event.h>
#include <linux/hw_breakpoint.h>
// opakuj:
struct perf_event_attr attrs;
memset(&attrs, 0, sizeof(attrs));
attrs.type = PERF_TYPE_HARDWARE;
attrs.size = sizeof(attrs);
attrs.config = PERF_COUNT_HW_INSTRUCTIONS;
attrs.exclude_user = 0;
attrs.exclude_kernel = 1;
attrs.exclude_hv = 1;
attrs.disabled = 1;
attrs.enable_on_exec = 1;
attrs.sample_period = instructionsLimit;
attrs.wakeup_events = 1;
fd = syscall(__NR_perf_event_open, attrs,
p, -1, -1, PERF_FLAG_FD_NO_GROUP);
fcntl(fd, F_SETOWN, getpid());
int oldFlags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, oldFlags | O_ASYNC);
void sigioHandler(int sig) {}
sigaction(SIGIO, sioioHandler);
// reaguj:
for (;;) {
int res = waitpid(p);
long long int instrs;
read(fd, &instrs, sizeof(instrs));
if (instrs > instructionsLimit && res != p) {
kill(p, SIGKILL);
return 1;
} else if (res == p) {
return 0;
}
}
#include <pmc.h>
#include <pmclog.h>
int tun[2];
pipe(tun);
pmc_id_t id;
pmc_allocate("instructions", PMC_MODE_TC,
PMC_F_LOG_PROCSW | PMC_F_LOG_PROCEXIT,
PMC_CPU_ANY, &id, -1);
pmc_configure_logfile(tun[1]);
pmc_attach(id, p);
pmc_start(id);
void* reader = pmclog_open(tun[0]);
struct pmclog_ev ev;
uint64_t instrs = 0;
for (;;) {
pmclog_read(reader, ev);
switch (ev.pl_type) {
case PMCLOG_TYPE_PROCCSW:
instrs += ev.pl_u.pl_c.pl_value;
break;
case PMCLOG_TYPE_PROCEXIT:
instrs += ev.pl_u.pl_e.pl_value;
}
if (instrs > instructions_limit) {
kill(p, SIGKILL);
return 1;
}
}
struct pmclog_ev {
enum pmclog_state pl_state; /* parser state */
off_t pl_offset; /* byte offset in stream */
size_t pl_count; /* count of records so far */
struct timespec pl_ts; /* log entry timestamp */
enum pmclog_type pl_type; /* log entry kind */
union { /* log entry data */
struct pmclog_ev_callchain pl_cc;
struct pmclog_ev_closelog pl_cl;
struct pmclog_ev_dropnotify pl_d;
struct pmclog_ev_initialize pl_i;
struct pmclog_ev_map_in pl_mi;
struct pmclog_ev_map_out pl_mo;
struct pmclog_ev_pmcallocate pl_a;
struct pmclog_ev_pmcallocatedyn pl_ad;
struct pmclog_ev_pmcattach pl_t;
struct pmclog_ev_pmcdetach pl_d;
struct pmclog_ev_proccsw pl_c;
struct pmclog_ev_procexec pl_x;
struct pmclog_ev_procexit pl_e;
struct pmclog_ev_procfork pl_f;
struct pmclog_ev_sysexit pl_e;
struct pmclog_ev_userdata pl_u;
} pl_u;
};
# kldload hwpmc
$ pmcstat -p instructions ./1-sec-prog
$ cat instructor.d
dtrace:::BEGIN
{
i = 0;
}
pid$target:::
{
i = i + 1;
}
dtrace:::END
{
trace(i);
}
$ dtrace -s instructor.d -c ./1-sec-prog
"na szybko":
// Linux
seccomp(SECCOMP_SET_MODE_STRICT, 0, NULL);
// FreeBSD
cap_enter();
// OpenBSD
pledge("", NULL);
#include <sys/ptrace.h>
#include <linux/user.h>
// dziecko zgłasza się
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
// rodzic po złapaniu sygnału odczytuje rejestr
eax = ptrace(PTRACE_PEEKUSER, child, 4 * ORIG_EAX, NULL);
switch (eax) {
case SYS_write:
case SYS_read:
/* ... */
break;
default:
ptrace(PTRACE_KILL, child, NULL, NULL);
return 1;
}
ptrace(PTRACE_SYSEMU, child, NULL, NULL);
syscall::fork:entry,
syscall::open:entry,
...
/pid == $target/
{
exit(1);
}