Jun 012018
 

A. Biutiful Number

link soal

Diberikan sebuah bilangan bulat N (1 \le N \le 1000000), tentukan apakah N adalah Biutiful Number.

Biutiful Number pada soal ini adalah Triangular Number, yaitu bilangan yang bisa dibentuk oleh penjumlahan deret aritmatika dengan beda 1 dan dimulai dari 1.

Untuk menentukan apakah sebuah bilangan N adalah Triangular Number, kita hanya perlu melakukan simulasi pembentukan Triangular Number.

bool yes[1000005] = {false};
int n    = 1;
int diff = 1;
while ( n <= 1000000 ) {
  yes[n] = true;
  diff++;
  n += diff;
}

Generator Triangular Number di atas memiliki kompleksitas O(\sqrt{N}). Untuk menjawab pertanyaan dari setiap kasus, kita hanya perlu memeriksa nilai dari array yes[N] dalam O(1). Alternatifnya, kita bisa melakukan simulasi pembentukan Triangular Number untuk setiap pertanyaan kasus yang diberikan (namun, tidak perlu disimpan di array), dengan total kompleksitas O(T\sqrt{N}).

Soal ini berhasil diselesaikan oleh semua tim di Babak Final.

B. Raon and Ice Cream

link soal

Diberikan sebuah string S (1 \le |S| \le 500000S; S_{i} \in \text{[A-Z]}, berapa jumlah potongan string terbanyak yang bisa dibentuk jika semua potongan string harus memiliki panjang dan karakter penyusun yang sama (urutan tidak penting)?

Sekilas terlihat solusi naif dengan mencoba semua panjang potongan dari \text{1}..|S| akan memiliki total kompleksitas O(|S|^{2}). Namun, jika kita hanya menguji panjang potongan yang merupakan kelipatan dari |S|, total kompleksitas solusi ini menjadi O(|S|.d(|S|)) di mana d(|S|) adalah banyaknya bilangan pembagi dari |S|. Dari 1 hingga 500000, bilangan yang memiliki pembagi terbanyak adalah 498960 dengan total 200 bilangan pembagi.

Pemeriksaan apakah sebuah panjang potongan akan menyebabkan semua potongan string mememiliki karakter penyusun yang sama, bisa dilakukan dalam O(|S|), atau tepatnya O(26.|S|), seperti yang diperlihatkan oleh potongaan kode di bawah.

bool is_cuttable(int len) {
  int goal[26] = {0};
  int curr[26] = {0};
  REP(i,len) goal[arr[i]]++;
  int  mark = len - 1;
  REP(i,N) {
    curr[arr[i]]++;
    if ( i == mark ) {
      REP(j,26) if ( curr[j] != goal[j] ) return false;
      memset(curr,0,sizeof(curr));
      mark += len;
    }
  }
  return true;
}

Namun demikian, total kompleksitas pemeriksaan untuk semua bilangan pembagi bukanlah OO(26.|S|.d(|S)|), melainkan O(26.\sigma(|S|)) di mana \sigma(|S|) adalah jumlah dari semua bilangan pembagi |S| – perhatikan bahwa perulangan di baris 9 hanya dilakukan ketika variable i mencapai panjang potongan (baris 8).

Solusi di atas ACCEPTED jika diimplementasikan dengan benar dan efisien, yaitu dengan menghindari penggunaan C++ STL yang tidak diperlukan. Untuk mempercepat solusi di atas, kita bisa menambahkan pruning dengan mengharuskan panjang potongannya yang akan diuji juga harus habis membagi jumlah masing-masing karakter penyusun.

Total 14 tim berhasil menyelesaikan soal ini di Babak Final.

C. Raon and Candy

link soal

Baca soal pada link di atas.

Untuk mempermudah penjelasan, “nilai” di sini diartikan sebagai “jumlah bebek” (banyak bebek dalam satu kandang), dan semua nilai sudah diurutkan secara tidak menurun.

Tentunya secara intuitif, agar total nilai pada akhirnya sesedikit mungkin, kandang bebek dengan nilai paling sedikit lah yang harus dipilih di setiap putarannya. Jika K cukup kecil (ct: K \le 10000000), maka soal ini bisa diselesaikan dengan menyimulasikan proses pemilihan nilainya. Simpan semua nilai dalam struktur data priority queue dan prioritaskan nilai terkecil. Ambil nilai terkecil dari priority queue, gandakan nilainya, simpan kembali ke dalam priority queue; ulangi langkah ini sebanyak K kali. Kompleksitas solusi ini adalah O(K\log{N}) Sayangnya, nilai K di soal ini bisa mencapai 1000000000, sehingga, solusi ini akan mendapatkan TIME-LIMIT.

Urutan pemilihan nilai dengan priority queue ini bisa tidak teratur tergantung dari nilai-nilainya. Yang dimaksud “tidak teratur” adalah tidak terlihat seperti memiliki pola. Contoh: {1, 5, 12}; di contoh ini, urutan pemilihannya: (1 1 1 2 1 2 3 …).

Namun, perhatikan apa yang terjadi ketika dua kali nilai terkecil lebih besar dari nilai terbesar. Jika hal ini terjadi, maka proses pemilihan nilai dengan priority queue akan menjadi teratur. Contoh: {5, 6, 7}. Di contoh ini, 5 * 2 > 7, dan urutan pemilihannya adalah (1 2 3 1 2 3 1 2 3 …). Pada kasus ini, kita bisa menghitung berapa banyak penggandaan yang terjadi pada masing-masing nilai dengan cepat. (K\bmod{N})+1 nilai terkecil akan digandakan sebanyak \lceil{K/N}\rceil kali, sedangkan sisanya akan digandakan sebanyak \lfloor{K/N}\rfloor kali. Dengan demikian, untuk mendapatkan akhir dari masing-masing nilai dalam kasus ini, kita hanya perlu mengalikan setiap nilai dengan dua-pangkat yang bersangkutan. Kompleksitas untuk melakukan hal ini adalah O(N+\log{K}) di mana faktor O(\log{K}) didapatkan karena pemangkatan dengan teknik exponentiation by squaring (cukup dilakukan dua kali saja, satu untuk 2^{\lceil{K/N}\rceil} dan satu untuk 2^{\lfloor{K/N}\rfloor}).

Kasus di atas akan terjadi ketika nilai terbesar di input (sebelum pemilihan dilakukan untuk pertama kalinya) sudah menjadi nilai terkecil. Contoh: {1, 5, 12} → {2, 5, 12} → {4, 5, 12} → {8, 5, 12} → {8, 10, 12} → {16, 10, 12} → {16, 20, 12}. Di mulai dari kondisi ini, urutan pemilihannya akan terus berulang. {12, 16, 20} → (1, 2, 3, 1, 2, 3, 1, 2, …).

Untungnya, angka terbesar yang bisa menjadi input untuk setiap nilainya hanyalah 1000000000. Sehingga, setiap nilai hanya akan digandakan sebanyak O(\log{A_i}) kali sebelum kasus di atas terjadi. Kompleksitas untuk menyimulasikan proses pemilihannya hingga nilai terbesarnya terpilih adalah O(N\log{A}\log{N}) – proses pemilihan akan berlangsung O(N\log{A}) kali, dan kompleksitas untuk sekali pemilihan dengan priority queue sadalah O(\log{N}).

Sehingga, kita bisa menyelesaikan soal ini dengan cara: Lakukan simulasi pemilihan hingga nilai terbesar di input menjadi nilai terkecil, kemudian lakukan perhitungan cepat untuk sisa pemilihannya. Kompleksitas solusi demikian adalah O(N\log{A}\log{N}+N+\log{K}).

Hanya ada satu tim yang berhasil menyelesaikan soal ini di Babak Final.

D. Parallel Lines

link soal

Diberikan N buah titik (1 \le N \le 2000) pada bidang Kartesian, tentukan jumlah garis paralel terbanyak yang bisa dibentuk; setiap garis parallel harus melewati setidaknya dua dari N titik yang diberikan, dan setiap titik hanya bisa dilewati maksimum sebuah garis.

Dua buah garis dikatakan paralel jika mereka memiliki gradient garis yang sama. Dengan demikian, kita bisa mengelompokan semua kemungkinan garis yang bisa dibentuk berdasarkan gradient-nya (\Delta{y} / \Delta{x}) dan menghitung ada berapa banyak garis untuk setiap gradient. Dengan N titik yang diberikan, kita bisa membentuk \binom{N}{2} garis, sehingga solusi ini memiliki kompleksitas O(N^2).

Namun solusi di atas BELUM mempertimbangkan kemungkinan garis yang melewati tiga atau lebih titik. Perhatikan bahwa soal ini tidak menjamin bahwa titik-titik yang diberikan bebas dari collinearity. Sehingga, jika ada (misalnya) 3 titik yang berada pada garis yang sama, solusi di atas akan menemukan bahwa terdapat \binom{3}{2} = 3 buah garis yang saling paralel meskipun sebenarnya hanya ada sebuah garis.

Dengan demikian, kita memerlukan cara lain untuk memeriksa berapa garis yang saling paralel di antara garis-garis dengan gradient yang sama. Ada beberapa cara yang bisa digunakan untuk mengatasi masalah collinearity ini, di antaranya:

  1. Dengan menggunakan struktur data Disjoint Set (cara yang saya gunakan). Gabungkan garis yang memiliki titik yang sama menjadi satu kelompok; hitung ada berapa kelompok yang terbentuk.
  2. Dengan menghitung ada berapa nilai konstanta c yang unik dari setiap persamaan garis y = mx + c.

Ada dua hal yang harus diperhatikan pada tahap implementasi setelah kita menemukan solusi di atas:

  1. Jangan menggunakan tipe data floating point (double) ketika kita menghitung gradient garis. Sebagai gantinya, gunakan pair-of-integer \langle{x}, y\rangle. Penggunaan tipe data floating point sangat berpotensi menyebabkan precision error (WRONG-ANSWER).
  2. Jangan menggunakan std::map ketika mengelompokkan garis berdasarkan gradientnya. Sebagai gantinya, gunakan teknik sorting (ct: std::sort). Penggunaan std::map meskipun memiliki kompleksitas yang sama dengan std::sort, O(N\log{N}), memiliki faktor konstanta dan overhead yang jauh lebih besar sehingga solusi demikian bisa mendapatkan TIME-LIMIT.

Tidak ada tim yang berhasil menyelesaikan soal ini di Babak Final.

E. Dependency Hell

link soal

Tentukan ada berapa banyak topological order valid dari sebuah rooted tree dengan N node (1 \le N \le 100000).

Jika tree yang diberikan hanya memiliki kedalaman 1 (semua node terhubung langsung dengan root), maka banyak topological order yang valid ada sebanyak (N-1)!, karena setiap node yang merupakan child dari root saling independent satu dengan yang lainnya (sehingga mereka bisa diletakkan di posisi manapun kecuali posisi terakhir yang merupakan posisi root). Jika tree yang diberikan memiliki kedalaman lebih dari 1, node yang ada di masing-masing subtree anak dari root tentunya tidak lagi saling independent; mereka juga harus memenuhi syarat topological order di subtree masing-masing.

Untuk menjelaskan solusi soal ini, perhatikan soal yang berhubungan berikut: Ada berapa banyak string yang terdiri dari 3 karakter A, 4 karakter B, dan 5 karakter C?

Banyak permutasi dari string dengan 3+4+5 = 12 karakter tentunya ada 12! Namun, dalam kasus ini, ada beberapa karakter yang sama (3A, 4B, dan 5C); sebagai akibatnya, permutasi A1BBA2CBA3CCBCC dianggap sama dengan permutasi A2BBA3CBA1CCBCC karena A1A2A3 = A2A3A1 = A1A3A2 = … yang merepresentasikan AAA. Dengan demikian, kita perlu membagi 12! tadi dengan banyaknya permutasi yang duplikat seperti ini, yaitu 3! (duplikat untuk A), 4! (duplikat untuk B), dan 5! (duplikat untuk C). Sehingga, banyaknya permutasi valid untuk soal ini adalah: \frac{12!}{3!4!5!}.

Kembali ke soal E. Kasus yang terjadi pada soal E mirip dengan soal di atas. Kita harus melakukan permutasi pada N-1 node (node selain root), namun permutasi pada masing-masing subtree harus mengikuti aturan topological order. Aturan topological order yang harus dipenuhi oleh setiap subtree bisa dinyatakan dalam bentuk relasi rekurens. Jadi, kita bisa menghitungnya dengan ada berapa permutasi dimana masing-masing permutasi subtree dianggap sama (seperti soal di atas) dikali dengan permutasi masing-masing subtree yang mengikuti aturan topological order. Ingat, pada permutasi topological order, node root harus menjadi yang terakhir.

Untuk mengatasi pembagian modular (perhatikan, output harus dimodulo dengan 1E9+7), kita bisa menggunakan modular multiplicative inverse, yang tentunya tidak sukar untuk dilakukan mengingat 1E9+7 adalah bilangan prima.

Berikut adalah contoh potongan kode rekursi untuk menyelesaikan soal ini:

int f(int x) {
  int ret = fac[nchild[x]-1];
  for ( auto &p : con[x] ) {
    ret = ((LL)ret * inverse_mod(fac[nchild[p]])) % mod;
    ret = ((LL)ret * f(p)) % mod;
  }
  return ret;
}

Hanya ada satu tim yang berhasil menyelesaikan soal ini di Babak Final.

F. Ocarth

link soal

Diberikan sebuah bilangan bulat K (1 \le K \le 16715312000), cari bilangan (dan digitnya) yang mengandung digit ke K pada string yang dibentuk oleh gabungan dari semua bilangan dari 1, contoh: 1234567…; semua bilangan yang ada pada soal ini ada dalam bentuk Octal (basis 8).

Jika semua bilangan memiliki jumlah digit yang sama, soal ini tentunya tidak sukar untuk diselesaikan. Contoh, semua bilangan memiliki 5 digit: 0000100002000030000400050000600070010, dst. Untuk mencari bilangan yang mengandung digit ke K, kita tinggal menghitung nilai dari \lceil{K/5}\rceil, dan untuk mencari digitnya, kita tinggal mencari digit ke (K-1) \bmod 5 (dimulai dari digit ke-0) pada bilangan tadi. Namun, di soal ini, tidak semua bilangan memiliki jumlah digit yang sama, ct: 1 4 7 adalah bilangan 1 digit, 13 35 62 adalah bilangan 2 digit, 324 447 574 adalah bilangan 3 digit, dst.

Sehingga, sebelum kita bisa menggunakan cara di atas, kita perlu mencari tahu terlebih dahulu: digit ke K berada pada rentang bilangan dengan berapa digit. Evaluasi setiap panjang digit dimulai dari 1, dan kurangi K dengan panjang digit dikali dengan banyaknya bliangan yang memiliki panjang digit demikian. Berhenti ketika jika K dikurangi akan menyebabkan nilainya lebih kecil dari 1.

Banyaknya bilangan dengan 1 digit: 7 – ct: 1, 2, …, 7
Banyaknya bilangan dengan 2 digit: 7 * 8 = 56 – ct: 10, 11, …, 77.
Banyaknya bilangan dengan 3 digit: 7 * 8 * 8 = 448 – ct: 100, 101, …, 777.
Banyaknya bilangan dengan 4 digit: 7 * 8 * 8 * 8 = 3548 – ct: 1000, 1001, …, 7777.
dst.

Satu hal yang harus diperhatikan di soal ini: SEMUA bilangan pada soal ini berada dalam bentuk OCTAL, termasuk output. Perhatikan contoh input/output #2, terutama bagian di mana Case #7 yang dilanjutkan dengan Case #10, bukan Case #8. Ya, ada alasannya mengapa layout soal ini agak berbeda dengan soal-soal lainnya.

Total ada 7 tim yang berhasil menyelesaikan soal ini di Babak Final.

G. Problem on Array

link soal

Baca soal pada link di atas.

Ada beberapa solusi yang bisa digunakan untuk menyelesaikan soal ini. Solusi saya menggunakan teknik yang mirip (secara kegunaan) dengan failure function di algoritma KMP, yaitu fungsi yang bisa membantu kita menentukan kemana kita harus “meloncat”. Solusi lainnya yang saya ketahui adalah menggunakan struktur data stack untuk mencari kemana kita harus meloncat. Di post ini saya akan membahas solusi yang menggunakan stack, meskipun menurut saya, solusi yang saya gunakan lebih keren 😀 Solusi ini saya pahami setelah saya mempelajari solusi Felix Halim dan solusi dari beberapa tim di kontes; ada beberapa tim yang menggunakan pendekatan stack, namun hanya 1 tim yang berhasil ACCEPTED.

Mula-mula, jika A_N adalah nilai terbesar, maka F_i pada soal ini sama dengan index j terkecil di mana i < j dan A_i \le A_j. Nilai F_i bisa dicari dengan bantuan struktur data stack. Setiap saat, stack yang kita buat harus berisi index i dengan urutan menurun berdasarkan elemennya, yaitu A_i > A_j untuk semua i < j di dalam stack. Untuk mencapai struktur demikian, setiap kali kita memroses A_i (dengan urutan 1 ke N), pop data dari stack selama data teratasnya masih menunjukkan elemen yang lebih kecil atau sama dengan A_i. Setiap kali data teratas dari stack (top) menunjukkan elemen yang lebih kecil atau sama dengan A_i, update F_{top} = i karena i adalah index terkecil bagi top di mana A_{top} \le A_i. Dengan proses ini, F_N tidak akan terupdate secara otomatis (karena proses update F_i di atas hanya terjadi ketika ada data baru yang diproses, sedangkan i = N adalah data terakhir). Sehingga, kita perlu mengupdate F_N = N secara langsung.

Setelah proses di atas dijalankan, F_i yang belum ditentukan nilainya hanyalah untuk i yang masih berada di dalam stack. Hal ini terjadi ketika A_N bukanlah nilai terbesar yang ada. Sekilas terlihat kita bisa menggunakan isi stack yang tersisa untuk menentukan F_i yang tersisa, yaitu F_i diisi dengan data stack berada di atasnya. Namun, cara ini akan menyebabkan F_i akan diisi dengan index j yang salah jika terdapat beberapa index yang nilainya sama dengan A_j yang seharusnya. Contoh: misalkan A_{1..5} = \{5, 4, 4, 4, 3\}, maka dengan cara ini akan menyebabkan F_1 = 4 (isi stack: [1, 4, 5]), padahal seharusnya F_1 = 2.

Masalah di atas bisa diatasi dengan cara membangun stack baru di mana setiap saat isinya harus berada dalam urutan tidak menaik, yaitu A_i \ge A_j untuk semua i < j di dalam stack. Cara membentuk stack ini mirip dengan cara sebelumnya, yaitu pop data dari stack selama data teratasnya masih menunjukkan elemen yang lebih kecil dari A_i. Di tahap ini, F_i tidak perlu diupdate (yang kita inginkan adalah struktur stacknya). Setelah stack ini terbentuk dengan memroses semua i=1..N, cara di atas bisa dilakukan untuk mengupdate F_i yang belum terisi di proses sebelumnya, yaitu: F_i diisi dengan data di atasnya (dalam stack). Dengan demikian, F_i yang berlum terisi tadi akan diisi dengan j yang benar. Di tahap ini, mungkin saja F_i yang sebelumnya sudah terisi menjadi terisi kembali, namun, nilai barunya bisa dipastikan sama dengan nilai sebelumnya.

Setelah semua F_i berhasil didapatkan, hitung G_i yang diperlukan.

Kompleksitas solusi ini adalah O(N).

Hanya ada satu tim yang berhasil menyelesaikan soal ini di Babak Final.

H. Captain Kaban

link soal

Diberikan nilai kekuatan 10 pemain utama dan nilai kekuatan N (1 \le N \le 10) pemain cadangan, tentukan total nilai kekuatan tim maksimum jika Anda diijinkan untuk menukar maksimum satu pemain utama dengan satu pemain cadangan.

Ini adalah soal termudah kedua di kontes ini. Yang perlu kita lakukan hanyalah mencari nilai kekuatan terendah dari pemain utama (\min_{main}) dan nilai kekuatan tertinggi dari pemain cadangan (\max_{reserve}). Tukar kedua pemain tersebut hanya jika \min_{main} < \max_{reserve}.

Total ada 27 tim yang berhasil menyelesaikan soal ini di Babak Final.

I. Irrigation

link soal

Diberikan sebuah array N\times{M}, cari sebuah posisi baris r dan kolom c sedemikian sehingga jika semua elemen pada array kecuali elemen pada baris r dan kolom c dijumlahkan akan menghasilkan jumlah terbesar.

Mula-mula, hitung jumlah semua elemen pada setiap baris (row[1..N]) dan setiap kolom (col[1..M]). Jika saluran irigasi dibangun pada baris r dan kolom c, maka total score yang kita dapatkan bisa dihitung dengan prinsip inklusi-eksklusi, yaitu: ALL – row[r] – col + arr[r] di mana ALL adalah jumlah semua elemen, dan arr[r] adalah elemen pada baris r dan kolom c.

Berikutnya, yang perlu kita lakukan adalah menguji semua r dan c yang valid dan cari yang menghasilkan total score paling tinggi. Jangan lupa untuk menangani aturan tie breaker yang diberikan pada soal. Komputasi jumlah semua elemen pada setiap baris memiliki kompleksitas O(NM), dan komputasi jumlah semua elemen pada setiap kolom memiliki kompleksitas O(NM). Kompleksitas untuk menghitung total score untuk setiap posisi r c adalah O(1), dan terdapat O(NM) posisi yang perlu diuji. Dengan demikian, total kompleksitas solusi ini adalah O(NM).

Total ada 14 tim yang berhasil menyelesaikan soal ini di Babak Final.

J. Raon and Voting

link soal

Baca soal pada link di atas.

Soal ini memiliki tiga buah query.

Query tipe 1: Gabungkan dua kelompok. Query ini bisa ditangani dengan struktur data disjoint set. Simpan data pemimpin tiap kelompok dalam array boss[1..N] dan banyaknya anggota kelompok dalam array size[1..N], sehingga kita bisa memeriksa siapa pemimpin suatu kelompok dan jumlah anggotanya dalam O(1). Jangan lupa update array boss[x] dan size[x] di mana x adalah a atau b tergantung siapa yang memiliki kelompok yang lebih besar. Simpan juga tuple \langle{leader,member}\rangle dalam sebuah priority queue di mana leader adalah pemimpin kelompok dan member adalah jumlah anggota kelompok tersebut; prioritaskan berdasarkan jumlah anggota kelompok. Data tuple ini akan kita gunakan untuk query tipe 3 nantinya.

Query tipe 2: Angkat satu anggota menjadi pemimpin kelompok. Di query ini, kita perlu melakukan modifikasi pada array boss[x] dan size[x]. Nilai x bisa dicari dengan operasi find(c) pada struktur data disjoint set. Setelah kedua array tersebut diupdate, berikutnya kita perlu juga mengupdate priority queue yang berisi pemimpin kelompok dan jumlah anggotanya. Dalam implementasinya, kita bisa menggunakan std::set untuk mengimplementasi priority queue yang mendukung operasi hapus.

Query tipe 3: Output pemimpin kelompok terbesar. Query ini bisa diselesaikan dalam O(1) jika kita sudah memiliki priority queue yang berisi tuple \langle{leader,size}\rangle di atas.

Total ada 6 tim yang berhasil menyelesaikan soal ini di Babak Final.

K. Echo Signal

link soal

Baca soal pada link di atas.

Soal ini sekilas terlihat sukar, namun memiliki solusi yang sangat sederhana.

Untuk menyelesaikan soal ini, kita perlu mengubah sudut pandang kita terhadap permasalahannya. Yang diinginkan soal ini adalah jumlah echo signal terbanyak yang bisa didapatkan oleh titik manapun dengan menjatuhkan initial signal di sembarang lattice point. Daripada mencari echo signal terbanyak secara langsung, alihkan pencarian kita ke berapa echo signal yang bisa didapatkan oleh sebuah titik.

Di mana kita harus menjatuhkan initial signal agar titik p bisa mendapatkan echo signal sebanyak mungkin? Ya, kita harus menjatuhkan initial signal di titik p itu sendiri. Dengan demikian, kita hanya perlu memeriksa ada berapa titik yang jaraknya tidak lebih dari R dari titik p untuk mengetahui berapa echo signal yang bisa didapatkan oleh titik p.

Lakukan pengujian untuk setiap titik dan kita bisa mengetahui titik mana yang mendapatkan echo signal maksimum.

Kompleksitas solusi ini adalah O(N^2).

Hanya ada 1 tim yang berhasil menyelesaikan soal ini pada 4 jam pertama kontes. Namun, pada jam terakhir, 4 tim lainnya juga berhasil menyelesaikan soal ini. Total ada 5 tim yang berhasil menyelesaikan soal ini di Babak Final.


 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)