OBDII Interface Project Source Code
http://www.oocities.org/sstandfast/OBDII.htm 1 // File: VPWM.jal
// Author: Shawn Standfast
// Version 1.00.2
// 11/1/2005
// Library for OBDII Variable Pulse Width Modulation on PIC16F877(A) @ 20MHz
//
// *Note - This library utilizes the CCPX Module, Timer 1, Timer 2 W/ Interrupts
// Also, be sure to be in Bank 0 before using any procedures in this
// library.
//
// This library is designed around the SAE J1850 VPWM standard. It is assumed
// that the bus is a CSMA/CR (Carrier Sense, Multiple Access, Collision Resolution)
// type bus. Ultimate bus control is determined by bit-by-bit arbitration. The
// general message format used is SOF + 1 or 3 Header Bytes + 10 or 8 Data Bytes
// + 1 CRC Byte + EOD + EOF. Max Frame Length = 12 Bytes
//
// Nominal Pulse widths are as follows:
// +-----------+--------------+
// | SYMBOL | Pulse Width |
// |-----------+--------------+
// | Active 1 | 64uS |
// | Passive 0 | 64uS |
// | |
// | Passive 1 | 128uS |
// | Active 0 | 128uS |
// | |
// | SOF | 200uS |
// | EOD | 200uS |
// | |
// | EOF | 280-300uS |
// +-----------+--------------+
// Functions: vpw_send(byte in data) return bit
// Procedures: vpw_receive()
// get_frame(byte in frame_num)
//
// I/O Pin Definitions and Directions
//
// pin_c2_direction = input
// pin_c1_direction = output
//
// vpwin is pin_c2
// vpwout is pin_c1 // Required Libraries:
include jpic // Set Bounds for Buffer Arrays
const array_check_indices = true const array0_start = 0xA0 // Output Array Start
const array0_end = 0xAC // Output Array End
const array1_start = 0xAD // Input Buffer Array 1 Start
const array1_end = 0xB9 // Input Buffer Array 1 End
const array2_start = 0xBA // Input Buffer Array 2 Start
const array2_end = 0xC6 // Input Buffer Array 2 End
const array3_start = 0xC7 // Input Buffer Array 3 Start
const array3_end = 0xD3 // Input Buffer Array 3 End
const array4_start = 0xD4 // Processing Buffer Array Start
const array4_end = 0xE0 // Processing Buffer Array End include bank_arrays // Other Constants
const rising = 0x05 // configure for capture on rising edge
const falling = 0x04 // configure for capture on falling edge
const per_short = 0x50 // number of cycles for 64uS for tmr1
const per_long = 0xA0 // number of cycles for 128uS for tmr1
const per_sof = 0xFA // number of cycles for 200uS for tmr1
const per_eof = 0xAF // #cycles 280uS, must use 1:8 prescaler for EOF detection
const comp_drive_low = 0x09 // for ccp2con to drive CCP2 pin low on compare
const comp_drive_high = 0x08 // for ccp2con to drive CCP2 pin high on compare
const comp_only = 0x0A // for ccp2con to flag only // I/O Pin Definitions and Directions
pin_c2_direction = input
pin_c1_direction = output
var bit vpwin is pin_c2
var bit vpwout is pin_c1
vpwout = false // Some Variables
// Byte Variables RESERVED FOR INTERRUPT ROUTINE
var byte tmr1_low_old = 0x00, tmr1_high_old = 0x00 // stores old tmr1 values
var byte tmr1_low_new = 0x00, tmr1_high_new = 0x00 // stores new tmr1 values
var byte delta_low = 0x00, delta_high = 0x00 // stores the difference between
// tmr1_old & tmr1_new
var bit pulse_rec = off // Configure ccpXmodule //--------------------------------------------------------
f877_ccp1con = 0x00
f877_ccp2con = 0x00 f877_ccpr2l = 0x00
f877_ccpr2h = 0x00 f877_ccpr1l = 0x00
f877_ccpr1h = 0x00 pir1_ccp1if = false // clear both CCP interrupt flags
pir2_ccp2if = false // Initialize Timer1------------------------------------------------------------
//
// max frame width = SOF + 11*(8 Data Bits) + 1 CRC Byte + EOF
// SOF = 200uS
// EOF = 300uS
// Max Byte Width (longest byte = 0b_1010_1010) = 128uS*8 = 1.024mS
// Max Data Width = 12*1024mS = 12.288mS
// max frame width = 12.788mS
// tmr1 overflows w/ a 1:4 prescaler @ 52.4288mS ample room for an entire frame
//
// //--------------------------------------------------------------------------- f877_t1con = 0x00 // 1:4 prescaler for timer1
t1ckps1 = on
tmr1if = false // clear interupt flag
f877_tmr1h = 0x00
f877_tmr1l = 0x00 // Initialize Timer 2 // --------------------------------------------------------
f877_t2con = 0x02 // 1:16 prescaler 1:1 postscaler for timer2
f877_tmr2 = 0x00 pir1_tmr2if = false // Initialize Periphial Interrupts // ------------------------------------------- asm BSF STATUS, // bank 1
tmr1ie = off // disable tmr1 interupt flag
pie1_ccp1ie = on // enable ccp1 interrupt flag
pie2_ccp2ie = off // disable ccp2 interrupt flag
pie1_tmr2ie = off // disable timer2 interrupts
f877_pr2 = 0x58
asm BCF STATUS, // bank 0 // disable interrupts //--------------------------------------------------------- intcon_gie = off
intcon_peie = off // vpw_idle_chk is for internal use to check for inactivity on the Com. Bus
procedure vpw_idle_chk is
tmr1on = false
vpwout = false // make sure only transmitting a low signal
pir2_ccp2if = false
t1ckps1 = on
t1ckps0 = on // set 1:8 prescaler for timer1 f877_tmr1l = 0x00 // reset timer one high and low bytes
f877_tmr1h = 0x00 f877_ccpr2l = per_eof // set period for compare to be ~280uS
f877_ccpr2h = 0x00 f877_ccp2con = comp_only // set CCP2 module to only flag when timer times out while vpwin loop end loop // loop until bus transisitions low tmr1on = on // start timer while ! pir2_ccp2if loop // wait while bus is low
if vpwin then // if activity detected on bus restart timer
f877_tmr1l = 0x00 // no need to reset high byte
end if
end loop pir2_ccp2if = false // clear interrupt flag tmr1on = false // stop timer 1 f877_tmr1l = 0x00 // reset timer 1
f877_tmr1h = 0x00 t1ckps0 = false // 1:4 prescaler for timer1
end procedure procedure crc_calc(byte in data, byte in out crc ) is // calculates the CRC byte
var byte bit_point = 0x80 // that is appended to the end of the OBD message Frame
var byte poly // NOTE* Procedure is to be called continuously for each
for loop // byte that is transmitted. However, once final byte is
if (bit_point & data) != then // passed through the CRC routine the final result in crc_reg
if (crc & 0x80) != then // must be complimented before appending to the message.
poly = 0x01 // For all messages, paramater CRC should be initialized to
else // 0xFF for the first itteration.
poly = 0x1C
end if
crc = ((crc << ) | ) ^ poly // original C Code for CRC posted on http:// obddiagnostics.com by B. Roadman
else // adapted to JAL by Shawn Standfast
poly = 0x00
if (crc & 0x80) != then
poly = 0x1D
end if
crc = (crc << ) ^ poly
end if
bit_point = bit_point >>
end loop
end procedure // Function vpw_send(byte in data) shifts out "data" one bit at a time
// MSB first. Arbritration is taken care of during transmission. If the
// transmission is successful then the function returns true else it returns
// false. Call procedure repeatedly to send multiple bytes. just be sure to
// only send one start of frame symbol per message frame. // Example Usage: *success is a var of type bit
// Send Single byte of data: success = vpw_send(data,true)
// tmr1on = false
// Send Multiple bytes in the same frame: success = vpw_send(data1,true)
// if success then
// success = vpw_send(data2,false)
// end if
// tmr1on = false
// Send "Array" of data:
// var bit send_sof = true
// var byte count = 0x00
// while ((success) & (count < arrayX_put_index)) loop
// temp = arrayX
// success = vpw_send(temp,send_sof)
// send_sof = false
// count = count + 1
// end loop
// tmr1on = false function vpw_send (byte in data, bit in send_sof) return bit is
asm bcf intcon_gie // disables interrupts while sending. otherwise we can get
asm bcf intcon_peie // into all sorts of trouble. :)
f877_ccp1con = 0x00
var bit error_flag = false
var volatile bit bit_out at data : // select bit to be transmitted
var bit dom_pass = false // keep track of active or passive symbol
var byte timer_low_byte, timer_high_byte, prtc_buf
var volatile byte next_bit = 0x00 // sets next pulse width for loop // shift data out one bit at a time; MSB first if bit_out then // if bit to be sent is a One
if dom_pass then // send "Active" One
next_bit = per_short
else // send "Passive" One
next_bit = per_long
end if
else // Bit to be sent is a Zero
if dom_pass then // send active zero
next_bit = per_long
else // send "Passive" zero
next_bit = per_short
end if
end if
// start of frame takes care of period adjustment for first bit. If current
// itteration is not sending a SOF, must adjust new period by adding pulse width
// to current ccp2H:ccp2L registers. if send_sof then // need to send a start of frame first?
// send start of frame plus first bit
vpw_idle_chk // verify bus is idle before beginning transmission f877_ccp2con = comp_drive_low // bus will be high for SOF. Drive bus low
// when pulse width is achieved. should also
// drive output pin high beginning transmission tmr1on = on // begin timing bus position f877_ccpr2l = per_sof // set period for compare to be ~200uS
f877_ccpr2h = 0x00 pir2_ccp2if = false error_flag = false // assume success unless failure occurs while ! pir2_ccp2if loop end loop // wait until timer2 times out. Once
// this loop is exited our SOF symbol
// will have finished and our output
// pin will be low.
// If the bus is still active then that means another node is still
// transmitting. The only other allowed active symbol that lasts for
// this duration is a BREAK symbol. So we poll the bus for the shortest
// allowed BREAK time. If this is passed then we will cease our attempt
// to transmit.
while vpwin loop // allows for nodes with slower clocks to finish their
assembler // SOF's.
local shorter
movf f877_tmr1h,w // The new starting point for the compare register
movwf f877_ccpr2h // is updated while the other nodes finish.
movf f877_tmr1l,w
movwf f877_ccpr2l
movf f877_tmr1h,w // ensures proper loading of CCP2 with the current
movwf f877_ccpr2h // timer value
bcf status_Z
movlw 0x01
subwf f877_ccpr2h,w // magnitude comparison of the current high byte
BTFSS status_Z // if the current timer value is greater than
GOTO shorter // 0x128 then the maximum allowed transmission
movlw 0x28 // length for a SOF has been reached. If it isnt
bsf status_C
subwf f877_ccpr2l,w // then we need to poll the bus again and repeat.
BTFSS status_C
GOTO shorter
bsf error_flag
shorter:
end assembler
if error_flag then
vpwout = false
tmr1on = false
f877_tmr1l = 0x00
f877_tmr1h = 0x00
f877_ccp2con = 0x00
return false
end if
end loop // SOF is always followed by data bytes. Prep for first bit to be sent
assembler // add next period to compare reference, 8-bit + 16-bit
bank MOVF next_bit,W
bank ADDWF f877_ccpr2l,f
BTFSC status_C
bank INCF f877_ccpr2h,f
end assembler asm clrf f877_ccp2con // first bit to be transmitted is always low
f877_ccp2con = comp_drive_high // set ccp2 to drive output high on match pir2_ccp2if = false // reset interrupt flag
send_sof = false // no more start of frame symbols to transmit
else // just send the remaining bits
assembler // add next period to compare reference. 8-bit + 16-bit
bank MOVF next_bit,W
bank ADDWF f877_ccpr2l,f
BTFSC status_C
bank INCF f877_ccpr2h,f
end assembler
end if while ! pir2_ccp2if loop // wait until end of period, when loop is
// exited bus transition should be done.
prtc_buf = port_c // Check for arbitration. If output does not
prtc_buf = prtc_buf & 0x06 // match input then arbitration may be lost.
if ((prtc_buf == 0x04) & (! pir2_ccp2if)) then
assembler
bcf tmr1on // Comparison between the bus transition time
// and the time remaining before bus expected
// transition is used to compensate for clock
// mismatch. Therefore false "lost arbritration"
// is avoided. This portion only checks for nodes
// that transition early. Nodes that transition
// later are dealt with after this portion.
bsf status_C
bcf status_Z local EXITE, EXIT
MOVF f877_tmr1l,W // determine delta between expected transition
SUBWF f877_ccpr2l,w // and actual transition time.
movwf timer_low_byte // timer_X_byte = ccpr2X - f877_tmr1X
MOVF f877_tmr1h,W
BTFSS status_C
INCF f877_tmr1h,W
SUBWF f877_ccpr2h,w
movwf timer_high_byte
btfss status, status_z // the difference between high bytes must be zero
goto EXITE
movlw 0x14 // to be within tolerance the difference must be less
bsf status_C // than 20 instructions. Setting the Carry/Borrow bit
subwf timer_low_byte,w // makes it available to borrow.
BTFSS status_C // If the low byte is >= 20 then a borrow
goto EXIT // will not have occured and status_c will still be set.
BTFSC status_Z // If the result is 0 then transition occured right on
goto EXIT // the boundary and is still valid.
EXITE: // check somewhere has not passed.
bsf error_flag
EXIT:
end assembler
if (error_flag) then // bus dominance lost.
vpwout = false // "Shut up and try again later"
tmr1on = false
f877_tmr1l = 0x00
f877_tmr1h = 0x00
f877_ccp2con = 0x00
return false
else // early transitioning node transitioned within specs. Change
f877_tmr1l = f877_ccpr2l // output and move on.
f877_tmr1h = f877_ccpr2h
tmr1on = on
end if
end if
if ((prtc_buf == 0x02) & (! pir2_ccp2if)) then // bus fault has been detected. Try again later.
vpwout = false
tmr1on = false
f877_tmr1l = 0x00
f877_tmr1h = 0x00
f877_ccp2con = 0x00
return false
end if
end loop pir2_ccp2if = false // reset ccp2 interrupt flag if dom_pass then // switch transition directions
// first must allow for nodes that are transmitting their active signals
// for just a little bit longer than we are. For the short pulse, the
// maximum allowed overshoot in time is 32uS and for the long pulse the
// maximum allowed overshoot in time is 34uS. Splitting the difference
// we will check for 33uS. However, I believe this to be incorrect and used 16uS.
if vpwin then // bus is still active
assembler
local loop1, done, exita
movlw comp_only
movwf f877_ccp2con
MOVlW 0x14
bank ADDWF f877_ccpr2l,f
BTFSC status_C
bank INCF f877_ccpr2h,f
loop1:
BTFSS vpwin // loops until either the input pin changes
goto done // or our "added" time expires.
BTFSS pir2_ccp2if
goto loop1
bcf tmr1on // if the program gets here then that means the input
bcf vpwout // is still set and our timer period has expired. If
clrf f877_tmr1l // we were sending a short pulse then it means arbitration
clrf f877_tmr1h // has been lost. If it is a long pulse then it could
clrf f877_ccp2con // mean a break symbol is being transmitted. Either way
bsf error_flag // we need to stop transmitting and exit.
bcf pir2_ccp2if
goto exita
done:
clrf f877_ccp2con // updates the compare registers with new
movf f877_tmr1h,w // starting values
movwf f877_ccpr2h
movf f877_tmr1l,w
movwf f877_ccpr2l
movf f877_tmr1h,w
movwf f877_ccpr2h
bcf pir2_ccp2if
exita:
end assembler
if error_flag then
return false
end if
end if
f877_ccp2con = comp_drive_high // if previously sending an active signal
dom_pass = false // next symbol will be passive. Ergo need
else // to drive bus high on next compare.
f877_ccp2con = comp_drive_low // Same logic here just opposite results
dom_pass = on // No need to check for devices with "longer"
end if // periods here because we have driven the
// bus high already.
data = data << // shift in next bit to be sent
end loop
return true
end function // procedure vpw_receive configures the ccp1 module to capture timer 1 and timer2
// to time inactivity. First ccp1 is configured to interrupt on the rising
// edge. On the first rising edge, timer 1 is started and the ccp1 module is
// reset for falling edge int. On the following edge interrupts, the two different
// captured timer 1 values are subtracted from each other to determine the
// pulse witdh. Then based upon which direction of the interrupting edge, the
// symbol is decoded. Once a SOF character has been decoded timer2 is enabled to start
// counting out 280uS to determine if IFS has been satisfied. Timer2 is reset
// on each valid pulse received. Therefore, timer2 clocks 280uS from the last bit received.
// Once a bit is received, it is placed in a bit buffer that is shifted left
// after each bit. When 8 bits have been received, that byte is placed into
// the first available frame buffer array. // ***NOTE*** In-Frame Response has NOT been implimented yet!! If you are using
// this library for a VPW system that requires IFR then you will need to add it.
// I will get around to adding it sometime in the near future but right now I do
// not need it (GM doesn't use IFR).
// //-------------------------------------------------------------------------- function vpw_receive return bit is var byte delta_low_old = 0x00, delta_high_old = 0x00 // buffers delta bytes
var volatile byte rec_buff = 0x00 // buffers the current received byte before
// loading into the buffer array
var byte bit_count = 0x00 // counts number of bits received
var volatile bit bit_rec = false // holds current received bit
var volatile bit data_rec = false // determines whether data has been received
var volatile bit bit_buff at rec_buff : // stores current received bit
var volatile bit long_short = false // flag indicating long or short pulse
var volatile bit brk_rec = false // flag indicating a BRK symbol has been received
var volatile byte ccpconfig = 0x00 // stores current ccp1 configuration
var volatile bit sof_rec = false f877_tmr1l = 0x00 // reset timer 1
f877_tmr1h = 0x00
tmr1_low_old = 0x00 // reset tmr1 storage variables
tmr1_high_old = 0x00
array4_put_index = 0x00 // reset processing buffer index to 0
pulse_rec = false
f877_ccp2con = 0x00 intcon_gie = on // enable interrupts
intcon_peie = on pir1_tmr2if = false vpw_idle_chk // wait until beginning of next frame before starting to receive asm clrf f877_ccp1con
f877_ccp1con = rising while ! pir1_tmr2if loop
while ! pulse_rec loop end loop
pulse_rec = false
delta_low_old = delta_low // buffer the delta values incase interrupt occurs
delta_high_old = delta_high // before we finish working with this pulse
ccpconfig = f877_ccp1con // buffer ccp1 configuration incase interrupt
// occurs before we finish working with this pulse if ((delta_high_old == 0x00) ) then
if delta_low_old >= 0xCC then
sof_rec = on
tmr2on = on
bit_count = 0x00
f877_tmr2 = 0x00
array4_put_index = 0x00
elsif ((delta_low_old <= 0xCB) & (delta_low_old >= 0x78)) then
long_short = on
data_rec = on
f877_tmr2 = 0x00
elsif ((delta_low_old <= 0x77) & (delta_low_old >= 0x2A)) then
long_short = off
data_rec = on
f877_tmr2 = 0x00
else
data_rec = false
end if
elsif ((delta_high_old == 0x01) ) then
if ((delta_low_old >= 0x2B) & (! pir1_tmr2if)) then
brk_rec = on
sof_rec = false
data_rec = false
long_short = false
tmr1on = false
tmr2on = false
f877_tmr1l = 0x00
f877_tmr1h = 0x00
f877_tmr2 = 0x00
array4_put_index = 0x00
tmr1_low_old = 0x00
tmr1_high_old = 0x00
delta_low_old = 0x00
delta_high_old = 0x00
asm clrf f877_ccp1con
f877_ccp1con = rising
elsif delta_low_old < 0x2B then
sof_rec = on
tmr2on = on
pir1_tmr2if = false
bit_count = 0x00
f877_tmr2 = 0x00
array4_put_index = 0x00
end if
end if
if data_rec & sof_rec then
if ccpconfig == rising then // if the next interrupt edge will be rising
if long_short then // then that means the previous pulse was active.
bit_rec = off // that means a long pulse = 0 and a short pulse = 1
else
bit_rec = on
end if
else // next interrupt edge will be falling, indicating the
if long_short then // previous pulse was passive. long_pulse = 1 & short_pulse = 0
bit_rec = on
else
bit_rec = off
end if
end if
rec_buff = rec_buff <<
bit_buff = bit_rec
data_rec = false
bit_count = bit_count +
end if
if bit_count == 0x08 then
array4 = rec_buff
bit_count = 0x00
end if
end loop
tmr1on = false
tmr2on = false
f877_ccp1con = 0x00
f877_tmr1l = 0x00
f877_tmr1h = 0x00
f877_tmr2 = 0x00
pir1_tmr2if = false
pir1_ccp1if = false intcon_gie = false
intcon_peie = false
return brk_rec
end function // Table for determining pulse widths from delta values:
// |long pulse| short pulse| SOF | break |
// | max | min | max | min | max | min | max | min |
// delta_high |0x00 | 0x00| 0x00 | 0x00| 0x01| 0x00| 0x01| 0x01|
// delta_low |0xCC | 0x78| 0x78 | 0x2A| 0x2B| 0xCC| 0x2B| 0x2B|
//
// Logic Flow: If delta_high > 0 then either SOF or BREAK
// if delta_low - 0x2B > 0 & delta_high > 0 then it is a break
// if delta_low - 0x2B <= 0 & delta_high > 0 then it is a SOF
// cases for delta_high == 0
// IF delta_low - 0xCC > 0 then it is a SOF
// If delta_low - 0x78 >= 0 & delta_low - 0xCC < 0 then it is a long pulse
// if delta_low - 0x2A >= 0 & delta_low - 0x78 < 0 then it is a short pulse
// if delta_low - 0x2A < 0 then it is too short procedure interrupt_handler is // edge has been detected on ccp1
pragma interrupt
tmr1_low_new = f877_ccpr1l
tmr1_high_new = f877_ccpr1h
// tmr1_new - tmr1_old = delta
assembler // 16-bit subtraction of old values from the new
btfss tmr1on
bsf tmr1on
bank MOVF tmr1_low_old,W
bank SUBWF tmr1_low_new,W
bank MOVWF delta_low
bank MOVF tmr1_high_old,W
BTFSS status_C
INCFSZ tmr1_high_old,W
bank SUBWF tmr1_high_new,W
bank MOVWF delta_high
end assembler
tmr1_low_old = tmr1_low_new // replace old values with new ones
tmr1_high_old = tmr1_high_new if ccp1m0 then // rising edge interrupt has been detected on ccp1
assembler
clrf f877_ccp1con // configure for falling edge
movlw falling
movwf f877_ccp1con
end assembler
else
// falling edge detected
assembler
clrf f877_ccp1con
movlw rising
movwf f877_ccp1con
end assembler
end if
pir1_ccp1if = false
pulse_rec = on
end procedure
OBDII Interface Project Source Code的更多相关文章
- Using command-line Subversion to access project source files
Help index About source code version control with Software Configuration Management (Subversion) Usi ...
- Tips for newbie to read source code
This post is first posted on my WeChat public account: GeekArtT Reading source code is always one bi ...
- Spring 4 MVC example with Maven - [Source Code Download]
In this tutorial, we show you a Spring 4 MVC example, using Maven build tool. Technologies used : Sp ...
- source code analyzer 功能强大的C/C++源代码分析软件 Celerity CRACK 破解版
特色 迅捷是一个功能强大的C/C++源代码分析软件.可以处理数百万行的源程序代码.支持标准及K&R风格的C/C++.对每一个打开的源代码工程,通过建立一个包含丰富交叉引用关系的数据库,显示其所 ...
- Indenting source code
Artistic Style 1.15.3 A Free , Fast and Small Automatic Formatterfor C , C++ , C# , Java Source Code ...
- How to build the Robotics Library from source code on Windows
The Robotics Library is an open source C++ library for robot kinematics, motion planning and control ...
- How to build windows azure PowerShell Source Code
Download any version source code of Windows Azure Powershell from https://github.com/Azure/azure-sdk ...
- 3 Ways of JDK Source Code Attachment in Eclipse---reference
You wanna look at a JVM class while you are coding and you cannot. Here is the solution. First of al ...
- Android Branch and master source code merge(patch)
Environment : Android 4.4.2 merge with Android 4.4.3(with other vendors source code) 1.确定你要merge 到 其 ...
随机推荐
- 易企秀H5 json配置文件解密分析
最近需要参考下易企秀H5的json配置文件,发现已经做了加密,其实前端的加密分析起来只是麻烦点. 抓包分析 先看一个H5: https://h5.eqxiu.com/s/XvEn30op F12可以看 ...
- nginx-fastcgi 反向代理
Nginx处理php页面 用fpm-server 基于fastcgi模块实现 Ngx_http_proxy_module 只能反代后端http server的主机 Ngx_fastcgi_prox ...
- Codeforces 1140F Extending Set of Points 线段树 + 按秩合并并查集 (看题解)
Extending Set of Points 我们能发现, 如果把x轴y轴看成点, 那么答案就是在各个连通块里面的x轴的个数乘以y轴的个数之和. 然后就变成了一个并查集的问题, 但是这个题目里面有撤 ...
- MLR:输入两个向量,得出两个向量之间的相关度—Jason niu
import numpy as np from astropy.units import Ybarn import math from statsmodels.graphics.tukeyplot i ...
- Codeforces 1105C Ayoub and Lost Array (计数DP)
<题目链接> 题目大意: 有一个长度为 n 的数列的未知数列,数列的每一个数的值都在区间 [l,r] 的范围内.现在问你能够构成多少个这样的数组,使得数组内的所有数的和能够被 3 整除. ...
- UVA136 Ugly Numbers【set】【优先队列】
丑数 丑数是指不能被2,3,5以外的其他素数整除的数.把丑数从小到大排列起来,结果如下: 1,2,3,4,5,6,8,9,10,12,15,… 求第1500个丑数. 提示:从小到大生成各个丑数.最小的 ...
- 笔记-JS高级程序设计-变量,作用域和内存问题
1在将一个值赋给变量时,解析器必须确认这个值是基本类值还是引用类型值,基本类型值是按值访问的,可以操作保存在在变量中的实际值,引用类型是保 存在内存中的对象,JS不允许直接访问内存中的位置,所以实际操 ...
- 004.MySQL双主+Keepalived高可用
一 基础环境 主机名 系统版本 MySQL版本 主机IP Master01 CentOS 6.8 MySQL 5.6 172.24.8.10 Master02 CentOS 6.8 MySQL 5.6 ...
- linux 学习笔记 groupadd创建组
1> groupadd -g test2 2>usermod -d /home/test -G test2 test 3>su user 4>groups 注意:root用户才 ...
- new关键字对构造函数做了什么
new 命令 基本用法 new 命令的作用,就是执行构造函数,返回一个实例对象. 1 var Vehicle = function (){ 2 this.price = 1000; 3 }; 4 5 ...