æ¦è¦
以ä¸ã®formatãPythonã§æåºããã°ãã
mycode = r''' # distutils: language=c++ # cython: language_level=3, boundscheck=False, wraparound=False, cdivision=True {ããã«cythonã®ã³ã¼ããæ¸ã} ''' import sys import os if sys.argv[-1] == 'ONLINE_JUDGE': # ã³ã³ãã¤ã«æ with open('mycode.pyx', 'w') as f: f.write(mycode) os.system('cythonize -i -3 -b mycode.pyx') import mycode
AtCoderã«ãããCythonæåºã®å¼±ç¹
Cythonã®çã®åã¯ãæ¢åã®CãC++ã®ã³ã¼ããã©ãããã¦å©ç¨ãããã¨ãã§ããç¹ã§ããã
ãã¨ãã°ãfrom libcpp.vector cimport vector
ãfrom libcpp.map cimport map
ã«ãã£ã¦C++ã®STLã³ã³ãããå©ç¨ãããã¨ãã§ããã
ãããAtCoderã§ã¯ãCythonã¯ãã¹ã¦Cã¸å¤æããã¦ãã¾ããããC++ã®ä¾¿å©ãªãã¼ã¿æ§é ãç¨ãããã¨ãã§ããªãã ãã®ç¾ç¶ã®ããã«ããã¨ãã°ç¾æ®µéã§ã¯ãé«éã«åçã«é åã確ä¿ããæ段(vector)ããªã(èªåã§æ¸ãã°ããã...)ãCythonã§listã使ã£ã¦ãå é¨ã§ã¯Pythonãå¼ã³åºãã¦ããããã«ç´ ã®Pythonã¨ãã»ã©å¤ãããªãå®è¡æéã«ãªãã ãããããã¯ä¾ãã°ã°ã©ããæ±ããããªåé¡ã§ã¯ä¸å©ã§ããã
解決æ¹æ³
Pythonæåºã®éã«ã³ã³ãã¤ã«ãã§ã¼ãºããããã¨ãå©ç¨ããã
AtCoderã§ã¯ããã¹ãã±ã¼ã¹ãå
¥åãããåã«ãå¼æ°ãsys.argv[-1] = 'ONLINE_JUDGE'
ã¨ãªããããªå®è¡ãèµ°ãããã®éã«ãCythonã®ã³ã¼ããèªåã®é½åã®è¯ãããã«(ã¤ã¾ãC++ã«å¤æ)ã³ã³ãã¤ã«ãã¦ãåä¸directoryã«ããã¦ãã¾ãã°ãCythonãå©ç¨ãã¦ãã¹ãã±ã¼ã¹ãé«éã«å®è¡ã§ããã
ãããåé ã«ã示ããä¸è¨ã®ã³ã¼ãã ãmycodeã®åé ã®shebangã®ãããªãã®ã¯ãCythonãC++ã«å¤æãé«éåãããªãã·ã§ã³ãè¨è¼ãããã®ã§ããã
mycode = r''' # distutils: language=c++ # cython: language_level=3, boundscheck=False, wraparound=False, cdivision=True {ããã«cythonã®ã³ã¼ããæ¸ã} ''' import sys import os if sys.argv[-1] == 'ONLINE_JUDGE': # ã³ã³ãã¤ã«æ with open('mycode.pyx', 'w') as f: f.write(mycode) os.system('cythonize -i -3 -b mycode.pyx') import mycode
æ§è½è©ä¾¡
Cythonã¨Pythonã§åé¡ã解ãã¦ã©ããããé«éåãããã®ãè¦ã¦ã¿ãã
UnionFindã使ããã®åé¡ã説ãã¦ã¿ãã
çµæã¯ä»¥ä¸ã®ããã«ãªã£ãã
å®è¡æé [ms] | |
---|---|
Python | 629 |
Cython | 77 |
Pythonã®èµ·åã«22msã»ã©ããããã¨ãããå¦çé¨åã«ã¤ãã¦ã¯ã11åãã®é«éåã«ãªã£ã¦ãããã¨ãèªã¿åãã ã¡ãªã¿ã«77msã¨ããã®ã¯Pythonæåºå ã§1ä½ã®é度ãè¨é²ããã
Pythonã®åç
import sys sys.setrecursionlimit(1 << 25) readline = sys.stdin.buffer.readline read = sys.stdin.readline # æååèªã¿è¾¼ãæã¯ãã£ã¡ def ints(): return list(map(int, readline().split())) class UnionFind: def __init__(self, N): self.N = N # ãã¼ãæ° self.n_groups = N # ã°ã«ã¼ãæ° # 親ãã¼ããããããè² ã¯èªèº«ã親ã¨ãããã¨ã self.parent = [-1] * N # idxãåãã¼ãã«å¯¾å¿ã def root(self, A): # ãã¼ãçªå·ãåãåã£ã¦ä¸çªä¸ã®è¦ªãã¼ãã®çªå·ã帰ã if (self.parent[A] < 0): return A self.parent[A] = self.root(self.parent[A]) # çµç±ãããã¼ããã¹ã¦ã®è¦ªãä¸æ¸ã return self.parent[A] def size(self, A): # ãã¼ãçªå·ãåãåã£ã¦ããã®ãã¼ããå«ã¾ãã¦ããéåã®ãµã¤ãºãè¿ãã return -self.parent[self.root(A)] def unite(self, A, B): # ãã¼ãçªå·ã2ã¤åãåã£ã¦ããã®ãã¼ãå士ãã¤ãªããå¦ç A = self.root(A) B = self.root(B) # ãã§ã«ãã£ã¤ãã¦ããå ´å if (A == B): return False # 大ããæ¹ã«å°ããæ¹ããã£ã¤ããã»ããå¦çã軽ãã®ã§å¤§å°æ¯è¼ if (self.size(A) < self.size(B)): A, B = B, A # ãã£ã¤ãã self.parent[A] += self.parent[B] # sizeã®æ´æ° self.parent[B] = A self.n_groups -= 1 return True def is_in_same(self, A, B): return self.root(A) == self.root(B) N, M = ints() uf = UnionFind(N) for _ in range(M): a, b = ints() uf.unite(a-1, b-1) print(-min(uf.parent))
Cythonã®åç
# distutils: language=c++ # cython: language_level=3, boundscheck=False, wraparound=False # cython: cdivision=True ctypedef long long LL from libc.stdio cimport scanf from libcpp.vector cimport vector ctypedef vector[LL] vec cdef class UnionFind: cdef: LL N,n_groups vec parent def __init__(self, LL N): self.N = N # ãã¼ãæ° self.n_groups = N # ã°ã«ã¼ãæ° # 親ãã¼ããããããè² ã¯èªèº«ã親ã¨ãããã¨ã self.parent = vec(N,-1) # é·ããªããªãã®ã§vectorã使ãå¿ è¦ã¯ãªãããã£ãããªã®ã§ cdef LL root(self, LL A): # ãã¼ãçªå·ãåãåã£ã¦ä¸çªä¸ã®è¦ªãã¼ãã®çªå·ã帰ã if (self.parent[A] < 0): return A self.parent[A] = self.root(self.parent[A]) # çµç±ãããã¼ããã¹ã¦ã®è¦ªãä¸æ¸ã return self.parent[A] cdef LL size(self, LL A): # ãã¼ãçªå·ãåãåã£ã¦ããã®ãã¼ããå«ã¾ãã¦ããéåã®ãµã¤ãºãè¿ãã return -self.parent[self.root(A)] cdef bint unite(self,LL A,LL B): # ãã¼ãçªå·ã2ã¤åãåã£ã¦ããã®ãã¼ãå士ãã¤ãªããå¦ç A = self.root(A) B = self.root(B) # ãã§ã«ãã£ã¤ãã¦ããå ´å if (A == B): return False # 大ããæ¹ã«å°ããæ¹ããã£ã¤ããã»ããå¦çã軽ãã®ã§å¤§å°æ¯è¼ if (self.size(A) < self.size(B)): A, B = B, A self.parent[A] += self.parent[B] # sizeã®æ´æ° self.parent[B] = A self.n_groups -= 1 return True cdef bint is_in_same(self,LL A,LL B): return self.root(A) == self.root(B) cdef LL N,M,_ scanf('%lld %lld',&N, &M) cdef UnionFind uf = UnionFind(N) cdef LL a,b for _ in range(M): scanf('%lld %lld',&a, &b) uf.unite(a-1, b-1) print(-min(uf.parent))
ã¾ã¨ã
æ¬è¨äºã§ã¯ãAtCoderã«ããã¦Cythonã®åãéæ¾ããã³ã¼ããç´¹ä»ããã
ãã®æ¹æ³ãç¨ããã¨ããã¾ã¾ã§ã¯ä½¿ããªãã£ãC++ã®STLã³ã³ãããCythonã§ãå©ç¨å¯è½ã¨ãªãããã¨ãã°vector
(Pythonã®list)ãmap
(Pythonã®dict)ãdeque
ãªã©ã§ããã
使ãããã®ã®ä¸è¦§ã¯ãã®ä¸ã«ããã
cython/Cython/Includes/libcpp at master · cython/cython · GitHub
ããã§Cythonã¯æ¸ããããã®æ©æµãnumpyãªã©ã®ã©ã¤ãã©ãªã®æ©æµãããã«C++ã®é度ã®æ©æµã享åãããã¨ã«ãªãã®ã§ããããã人æ°ãåºã¦ããã®ã§ã¯ãªããã¨æããæ¸å¿µãã¹ãã¯ãµãã¼ããã¦ããeditorãå£æ» çãªç¹ã¨æ å ±ãå°ãªãç¹ã ããã
ããã¦æå¾ã«Cythonãpythonæè¦ã§å®è¡ããã³ãã³ããããã¦ãããç»é²ãã¦ããã¨ä¾¿å©ã ã¨ããããä¸è¨ã¯fish shellã®ãã®ã§ãããä»ã®shellã«ã¤ãã¦ãå°ãæ¸ãæããã°åãã ããã
function run_cython set stem (string split ".pyx" "" $argv); and\ cythonize -3 -i $argv > /dev/null ; and\ python -c "import $stem" end
Cythonã¦ã¼ã¶ã¼ãä¸äººã§ãå¢ãããã¨ãæå¾ ãã¦ã